nim-dagger/tests/contracts/testContracts.nim
Eric e8e9820d5b
feat: add --payout-address (#870)
* feat: add `--payout-address`

Allows SPs to be paid out to a separate address, keeping their profits secure.
Supports https://github.com/codex-storage/codex-contracts-eth/pull/144 in the nim-codex client.

* Remove optional payoutAddress

Change --payout-address so that it is no longer optional. There is no longer an overload in `Marketplace.sol` for `fillSlot` accepting no `payoutAddress`.

* Update integration tests to include --payout-address

* move payoutAddress from fillSlot to freeSlot

* Update integration tests to use required payoutAddress

- to make payoutAddress required, the integration tests needed to avoid building the cli params until just before starting the node, otherwise if cli params were added ad-hoc, there would be an error after a non-required parameter was added before a required parameter.

* support client payout address

- withdrawFunds requires a withdrawAddress parameter, directs payouts for withdrawing of client funds (for a cancelled request) to go to that address.

* fix integration test

adds --payout-address to validators

* refactor: support withdrawFunds and freeSlot optional parameters

- withdrawFunds has an optional parameter for withdrawRecipient
- freeSlot has optional parameters for rewardRecipient and collateralRecipient
- change --payout-address to --reward-recipient to match contract signature naming

* Revert "Update integration tests to include --payout-address"

This reverts commit 8f9535cf35b0f2b183ac4013a7ed11b246486964.
There are some valid improvements to the integration tests, but they can be handled in a separate PR.

* small fix

* bump contracts to fix marketplace spec

* bump codex-contracts-eth, now rebased on master

* bump codex-contracts-eth

now that feat/reward-address has been merged to master

* clean up, comments
2024-09-17 04:18:15 +00:00

118 lines
4.6 KiB
Nim

import pkg/chronos
import pkg/ethers/testing
import pkg/ethers/erc20
import codex/contracts
import ../ethertest
import ./examples
import ./time
import ./deployment
ethersuite "Marketplace contracts":
let proof = Groth16Proof.example
var client, host: Signer
var rewardRecipient, collateralRecipient: Address
var marketplace: Marketplace
var token: Erc20Token
var periodicity: Periodicity
var request: StorageRequest
var slotId: SlotId
proc switchAccount(account: Signer) =
marketplace = marketplace.connect(account)
token = token.connect(account)
setup:
client = ethProvider.getSigner(accounts[0])
host = ethProvider.getSigner(accounts[1])
rewardRecipient = accounts[2]
collateralRecipient = accounts[3]
let address = Marketplace.address(dummyVerifier = true)
marketplace = Marketplace.new(address, ethProvider.getSigner())
let tokenAddress = await marketplace.token()
token = Erc20Token.new(tokenAddress, ethProvider.getSigner())
let config = await marketplace.config()
periodicity = Periodicity(seconds: config.proofs.period)
request = StorageRequest.example
request.client = await client.getAddress()
switchAccount(client)
discard await token.approve(marketplace.address, request.price)
discard await marketplace.requestStorage(request)
switchAccount(host)
discard await token.approve(marketplace.address, request.ask.collateral)
discard await marketplace.fillSlot(request.id, 0.u256, proof)
slotId = request.slotId(0.u256)
proc waitUntilProofRequired(slotId: SlotId) {.async.} =
let currentPeriod = periodicity.periodOf(await ethProvider.currentTime())
await ethProvider.advanceTimeTo(periodicity.periodEnd(currentPeriod))
while not (
(await marketplace.isProofRequired(slotId)) and
(await marketplace.getPointer(slotId)) < 250
):
await ethProvider.advanceTime(periodicity.seconds)
proc startContract() {.async.} =
for slotIndex in 1..<request.ask.slots:
discard await token.approve(marketplace.address, request.ask.collateral)
discard await marketplace.fillSlot(request.id, slotIndex.u256, proof)
test "accept marketplace proofs":
switchAccount(host)
await waitUntilProofRequired(slotId)
discard await marketplace.submitProof(slotId, proof)
test "can mark missing proofs":
switchAccount(host)
await waitUntilProofRequired(slotId)
let missingPeriod = periodicity.periodOf(await ethProvider.currentTime())
let endOfPeriod = periodicity.periodEnd(missingPeriod)
await ethProvider.advanceTimeTo(endOfPeriod + 1)
switchAccount(client)
discard await marketplace.markProofAsMissing(slotId, missingPeriod)
test "can be paid out at the end":
switchAccount(host)
let address = await host.getAddress()
await startContract()
let requestEnd = await marketplace.requestEnd(request.id)
await ethProvider.advanceTimeTo(requestEnd.u256 + 1)
let startBalance = await token.balanceOf(address)
discard await marketplace.freeSlot(slotId)
let endBalance = await token.balanceOf(address)
check endBalance == (startBalance + request.ask.duration * request.ask.reward + request.ask.collateral)
test "can be paid out at the end, specifying reward and collateral recipient":
switchAccount(host)
let hostAddress = await host.getAddress()
await startContract()
let requestEnd = await marketplace.requestEnd(request.id)
await ethProvider.advanceTimeTo(requestEnd.u256 + 1)
let startBalanceHost = await token.balanceOf(hostAddress)
let startBalanceReward = await token.balanceOf(rewardRecipient)
let startBalanceCollateral = await token.balanceOf(collateralRecipient)
discard await marketplace.freeSlot(slotId, rewardRecipient, collateralRecipient)
let endBalanceHost = await token.balanceOf(hostAddress)
let endBalanceReward = await token.balanceOf(rewardRecipient)
let endBalanceCollateral = await token.balanceOf(collateralRecipient)
check endBalanceHost == startBalanceHost
check endBalanceReward == (startBalanceReward + request.ask.duration * request.ask.reward)
check endBalanceCollateral == (startBalanceCollateral + request.ask.collateral)
test "cannot mark proofs missing for cancelled request":
let expiry = await marketplace.requestExpiry(request.id)
await ethProvider.advanceTimeTo((expiry + 1).u256)
switchAccount(client)
let missingPeriod = periodicity.periodOf(await ethProvider.currentTime())
await ethProvider.advanceTime(periodicity.seconds)
check await marketplace
.markProofAsMissing(slotId, missingPeriod)
.reverts("Slot not accepting proofs")