diff --git a/codex/contracts/Readme.md b/codex/contracts/Readme.md index a05edbd0..96c96667 100644 --- a/codex/contracts/Readme.md +++ b/codex/contracts/Readme.md @@ -43,10 +43,6 @@ let config = await marketplace.config() let collateral = config.collateral.initialAmount ``` -The host then needs to prepare a payment to the smart contract by calling the -`approve` method on the [ERC20 token][2]. Note that interaction with ERC20 -contracts is not part of this library. - After preparing the payment, the host can deposit collateral: ```nim await storage @@ -83,9 +79,7 @@ let request : StorageRequest = ( When a client wants to submit this request to the network, it needs to pay the maximum price to the smart contract in advance. The difference between the -maximum price and the offered price will be reimbursed later. To prepare, the -client needs to call the `approve` method on the [ERC20 token][2]. Note that -interaction with ERC20 contracts is not part of this library. +maximum price and the offered price will be reimbursed later. Once the payment has been prepared, the client can submit the request to the network: @@ -152,7 +146,7 @@ Storage proofs Time is divided into periods, and each period a storage proof may be required from the host. The odds of requiring a storage proof are negotiated through the storage request. For more details about the timing of storage proofs, please -refer to the [design document][3]. +refer to the [design document][2]. At the start of each period of time, the host can check whether a storage proof is required: @@ -178,5 +172,4 @@ await storage ``` [1]: https://github.com/status-im/codex-contracts-eth/ -[2]: https://ethereum.org/en/developers/docs/standards/tokens/erc-20/ -[3]: https://github.com/status-im/codex-research/blob/main/design/storage-proof-timing.md +[2]: https://github.com/status-im/codex-research/blob/main/design/storage-proof-timing.md diff --git a/codex/contracts/market.nim b/codex/contracts/market.nim index acefe06c..ff2dbcbc 100644 --- a/codex/contracts/market.nim +++ b/codex/contracts/market.nim @@ -25,6 +25,12 @@ func new*(_: type OnChainMarket, contract: Marketplace): OnChainMarket = signer: signer, ) +method approveFunds*(market: OnChainMarket, amount: UInt256) {.async.} = + let tokenAddress = await market.contract.token() + let token = Erc20Token.new(tokenAddress, market.signer) + + await token.approve(market.contract.address(), amount) + method getSigner*(market: OnChainMarket): Future[Address] {.async.} = return await market.signer.getAddress() diff --git a/codex/contracts/marketplace.nim b/codex/contracts/marketplace.nim index b16e4206..f23f9aee 100644 --- a/codex/contracts/marketplace.nim +++ b/codex/contracts/marketplace.nim @@ -1,4 +1,5 @@ import pkg/ethers +import pkg/ethers/erc20 import pkg/json_rpc/rpcclient import pkg/stint import pkg/chronos @@ -8,6 +9,7 @@ import ./config export stint export ethers +export erc20 export config type @@ -31,6 +33,7 @@ type proc config*(marketplace: Marketplace): MarketplaceConfig {.contract, view.} +proc token*(marketplace: Marketplace): Address {.contract, view.} proc slashMisses*(marketplace: Marketplace): UInt256 {.contract, view.} proc slashPercentage*(marketplace: Marketplace): UInt256 {.contract, view.} proc minCollateralThreshold*(marketplace: Marketplace): UInt256 {.contract, view.} diff --git a/codex/contracts/testtoken.nim b/codex/contracts/testtoken.nim deleted file mode 100644 index 175d82c2..00000000 --- a/codex/contracts/testtoken.nim +++ /dev/null @@ -1,10 +0,0 @@ -import pkg/chronos -import pkg/stint -import pkg/ethers - -type - TestToken* = ref object of Contract - -proc mint*(token: TestToken, holder: Address, amount: UInt256) {.contract.} -proc approve*(token: TestToken, spender: Address, amount: UInt256) {.contract.} -proc balanceOf*(token: TestToken, account: Address): UInt256 {.contract, view.} diff --git a/codex/market.nim b/codex/market.nim index 6aecac59..dd78c381 100644 --- a/codex/market.nim +++ b/codex/market.nim @@ -1,6 +1,7 @@ import pkg/chronos import pkg/upraises import pkg/questionable +import pkg/ethers/erc20 import ./contracts/requests import ./clock @@ -18,6 +19,10 @@ type OnRequestCancelled* = proc(requestId: RequestId) {.gcsafe, upraises:[].} OnRequestFailed* = proc(requestId: RequestId) {.gcsafe, upraises:[].} +method approveFunds*(market: Market, amount: UInt256) {.base, async.} = + ## This is generally needed for On-Chain ERC20 functionality to approve funds transfer to marketplace contract + raiseAssert("not implemented") + method getSigner*(market: Market): Future[Address] {.base, async.} = raiseAssert("not implemented") diff --git a/codex/purchasing/states/pending.nim b/codex/purchasing/states/pending.nim index 8ade593c..db2003c1 100644 --- a/codex/purchasing/states/pending.nim +++ b/codex/purchasing/states/pending.nim @@ -10,6 +10,7 @@ method enterAsync(state: PurchasePending) {.async.} = raiseAssert "invalid state" try: + await purchase.market.approveFunds(request.price()) await purchase.market.requestStorage(request) except CatchableError as error: state.switch(PurchaseErrored(error: error)) diff --git a/docs/TWOCLIENTTEST.md b/docs/TWOCLIENTTEST.md index 2e2f715a..1f888fc6 100644 --- a/docs/TWOCLIENTTEST.md +++ b/docs/TWOCLIENTTEST.md @@ -28,10 +28,10 @@ Open a terminal and run: Optionally, if you want to use the Marketplace blockchain functionality, you need to also include these flags: `--persistence --eth-account=`, where `account` can be one following: - - `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266` - `0x70997970C51812dc3A010C7d01b50e0d17dc79C8` - `0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC` - `0x90F79bf6EB2c4f870365E785982E1f101E93b906` + - `0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65` **For each node use a different account!** diff --git a/tests/codex/helpers/mockmarket.nim b/tests/codex/helpers/mockmarket.nim index b91cf0e9..df5b8dc4 100644 --- a/tests/codex/helpers/mockmarket.nim +++ b/tests/codex/helpers/mockmarket.nim @@ -80,6 +80,9 @@ proc new*(_: type MockMarket): MockMarket = ) MockMarket(signer: Address.example, config: config) +method approveFunds*(market: MockMarket, amount: UInt256) {.async.} = + discard + method getSigner*(market: MockMarket): Future[Address] {.async.} = return market.signer diff --git a/tests/contracts/testCollateral.nim b/tests/contracts/testCollateral.nim index 2fef14f9..6cf12b29 100644 --- a/tests/contracts/testCollateral.nim +++ b/tests/contracts/testCollateral.nim @@ -1,7 +1,7 @@ import pkg/chronos import pkg/stint import codex/contracts -import codex/contracts/testtoken +import ./token import ../ethertest ethersuite "Collateral": diff --git a/tests/contracts/testContracts.nim b/tests/contracts/testContracts.nim index e9980480..9ca6dc2b 100644 --- a/tests/contracts/testContracts.nim +++ b/tests/contracts/testContracts.nim @@ -2,11 +2,11 @@ import std/json import pkg/chronos import pkg/ethers/testing import codex/contracts -import codex/contracts/testtoken import codex/storageproofs import ../ethertest import ./examples import ./time +import ./token ethersuite "Marketplace contracts": let proof = exampleProof() diff --git a/tests/contracts/testMarket.nim b/tests/contracts/testMarket.nim index 1f0cb22b..36dfb32b 100644 --- a/tests/contracts/testMarket.nim +++ b/tests/contracts/testMarket.nim @@ -2,11 +2,11 @@ import std/options import pkg/chronos import pkg/stew/byteutils import codex/contracts -import codex/contracts/testtoken import codex/storageproofs import ../ethertest import ./examples import ./time +import ./token ethersuite "On-Chain Market": let proof = exampleProof() diff --git a/tests/contracts/token.nim b/tests/contracts/token.nim new file mode 100644 index 00000000..14c79839 --- /dev/null +++ b/tests/contracts/token.nim @@ -0,0 +1,9 @@ +import pkg/chronos +import pkg/stint +import pkg/ethers +import pkg/ethers/erc20 + +type + TestToken* = ref object of Erc20Token + +proc mint*(token: TestToken, holder: Address, amount: UInt256) {.contract.} diff --git a/tests/integration/tokens.nim b/tests/integration/tokens.nim index a27ea55c..dd114e96 100644 --- a/tests/integration/tokens.nim +++ b/tests/integration/tokens.nim @@ -1,5 +1,6 @@ +import pkg/ethers/erc20 import codex/contracts -import codex/contracts/testtoken +import ../contracts/token proc mint*(signer: Signer, amount = 1_000_000.u256) {.async.} = ## Mints a considerable amount of tokens and approves them for transfer to @@ -7,10 +8,13 @@ proc mint*(signer: Signer, amount = 1_000_000.u256) {.async.} = let token = TestToken.new(!deployment().address(TestToken), signer) let marketplace = Marketplace.new(!deployment().address(Marketplace), signer) await token.mint(await signer.getAddress(), amount) - await token.approve(marketplace.address, amount) proc deposit*(signer: Signer) {.async.} = ## Deposits sufficient collateral into the Marketplace contract. let marketplace = Marketplace.new(!deployment().address(Marketplace), signer) let config = await marketplace.config() + let tokenAddress = await marketplace.token() + let token = Erc20Token.new(tokenAddress, signer) + + await token.approve(marketplace.address, config.collateral.initialAmount) await marketplace.deposit(config.collateral.initialAmount) diff --git a/vendor/nim-ethers b/vendor/nim-ethers index 577e02b8..3c12a657 160000 --- a/vendor/nim-ethers +++ b/vendor/nim-ethers @@ -1 +1 @@ -Subproject commit 577e02b8a25198d6897c1f4871b5fd8e1f859e5a +Subproject commit 3c12a65769b9a223028df25f78abb6dde06fef35