Arnaud 28a83db69e
chore: returns the collateral when a slot is reserved but not filled (#1216)
* Change token allowance method because increaseAllowance does not exist anymore

* Returns collateral when a reservation is deleted and not only a slot is filled

* Remove the returnedCollateral when the slot is not filled by the host

* Add returnedCollateral when the sale is ignored

* Add returnsCollateral variable for ignored state

* Rebase the contracts submodule on the master

* Add integration test

* Fix duration

* Remove unnecessary teardown function

* Remove misleading comment

* Get returned collateral from the request

* Enable logs to debug on CI

* Fix test

* Increase test timeout

* Fix typo

* Fix rebase
2025-05-29 14:47:37 +00:00

114 lines
3.7 KiB
Nim

import pkg/questionable
import pkg/chronos
import pkg/codex/contracts/requests
import pkg/codex/sales/states/cancelled
import pkg/codex/sales/states/errored
import pkg/codex/sales/salesagent
import pkg/codex/sales/salescontext
import pkg/codex/market
from pkg/codex/utils/asyncstatemachine import State
import ../../../asynctest
import ../../examples
import ../../helpers
import ../../helpers/mockmarket
import ../../helpers/mockclock
asyncchecksuite "sales state 'cancelled'":
let request = StorageRequest.example
let slotIndex = request.ask.slots div 2
let clock = MockClock.new()
let currentCollateral = UInt256.example
var market: MockMarket
var state: SaleCancelled
var agent: SalesAgent
var reprocessSlotWas: ?bool
var returnedCollateralValue: ?UInt256
setup:
market = MockMarket.new()
let onCleanUp = proc(
reprocessSlot = false, returnedCollateral = UInt256.none
) {.async: (raises: []).} =
reprocessSlotWas = some reprocessSlot
returnedCollateralValue = returnedCollateral
let context = SalesContext(market: market, clock: clock)
agent = newSalesAgent(context, request.id, slotIndex, request.some)
agent.onCleanUp = onCleanUp
state = SaleCancelled.new()
reprocessSlotWas = bool.none
returnedCollateralValue = UInt256.none
teardown:
reprocessSlotWas = bool.none
returnedCollateralValue = UInt256.none
test "calls onCleanUp with reprocessSlot = true, and returnedCollateral = currentCollateral":
market.fillSlot(
requestId = request.id,
slotIndex = slotIndex,
proof = Groth16Proof.default,
host = await market.getSigner(),
collateral = currentCollateral,
)
discard await state.run(agent)
check eventually reprocessSlotWas == some false
check eventually returnedCollateralValue == some currentCollateral
test "completes the cancelled state when free slot error is raised and the collateral is returned when a host is hosting a slot":
market.fillSlot(
requestId = request.id,
slotIndex = slotIndex,
proof = Groth16Proof.default,
host = await market.getSigner(),
collateral = currentCollateral,
)
let error =
newException(SlotStateMismatchError, "Failed to free slot, slot is already free")
market.setErrorOnFreeSlot(error)
let next = await state.run(agent)
check next == none State
check eventually reprocessSlotWas == some false
check eventually returnedCollateralValue == some currentCollateral
test "completes the cancelled state when free slot error is raised and the collateral is not returned when a host is not hosting a slot":
discard market.reserveSlot(requestId = request.id, slotIndex = slotIndex)
market.fillSlot(
requestId = request.id,
slotIndex = slotIndex,
proof = Groth16Proof.default,
host = Address.example,
collateral = currentCollateral,
)
let error =
newException(SlotStateMismatchError, "Failed to free slot, slot is already free")
market.setErrorOnFreeSlot(error)
let next = await state.run(agent)
check next == none State
check eventually reprocessSlotWas == some false
check eventually returnedCollateralValue == UInt256.none
test "calls onCleanUp and returns the collateral when an error is raised":
market.fillSlot(
requestId = request.id,
slotIndex = slotIndex,
proof = Groth16Proof.default,
host = Address.example,
collateral = currentCollateral,
)
let error = newException(MarketError, "")
market.setErrorOnGetHost(error)
let next = !(await state.run(agent))
check next of SaleErrored
let errored = SaleErrored(next)
check errored.error == error