fix: approving tokens transfer when creating request (#385)
This commit is contained in:
parent
d756bf9dc5
commit
3198db414d
|
@ -43,10 +43,6 @@ let config = await marketplace.config()
|
||||||
let collateral = config.collateral.initialAmount
|
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:
|
After preparing the payment, the host can deposit collateral:
|
||||||
```nim
|
```nim
|
||||||
await storage
|
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
|
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 to the smart contract in advance. The difference between the
|
||||||
maximum price and the offered price will be reimbursed later. To prepare, the
|
maximum price and the offered price will be reimbursed later.
|
||||||
client needs to call the `approve` method on the [ERC20 token][2]. Note that
|
|
||||||
interaction with ERC20 contracts is not part of this library.
|
|
||||||
|
|
||||||
Once the payment has been prepared, the client can submit the request to the
|
Once the payment has been prepared, the client can submit the request to the
|
||||||
network:
|
network:
|
||||||
|
@ -152,7 +146,7 @@ Storage proofs
|
||||||
Time is divided into periods, and each period a storage proof may be required
|
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
|
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
|
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
|
At the start of each period of time, the host can check whether a storage proof
|
||||||
is required:
|
is required:
|
||||||
|
@ -178,5 +172,4 @@ await storage
|
||||||
```
|
```
|
||||||
|
|
||||||
[1]: https://github.com/status-im/codex-contracts-eth/
|
[1]: https://github.com/status-im/codex-contracts-eth/
|
||||||
[2]: https://ethereum.org/en/developers/docs/standards/tokens/erc-20/
|
[2]: https://github.com/status-im/codex-research/blob/main/design/storage-proof-timing.md
|
||||||
[3]: https://github.com/status-im/codex-research/blob/main/design/storage-proof-timing.md
|
|
||||||
|
|
|
@ -25,6 +25,12 @@ func new*(_: type OnChainMarket, contract: Marketplace): OnChainMarket =
|
||||||
signer: signer,
|
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.} =
|
method getSigner*(market: OnChainMarket): Future[Address] {.async.} =
|
||||||
return await market.signer.getAddress()
|
return await market.signer.getAddress()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import pkg/ethers
|
import pkg/ethers
|
||||||
|
import pkg/ethers/erc20
|
||||||
import pkg/json_rpc/rpcclient
|
import pkg/json_rpc/rpcclient
|
||||||
import pkg/stint
|
import pkg/stint
|
||||||
import pkg/chronos
|
import pkg/chronos
|
||||||
|
@ -8,6 +9,7 @@ import ./config
|
||||||
|
|
||||||
export stint
|
export stint
|
||||||
export ethers
|
export ethers
|
||||||
|
export erc20
|
||||||
export config
|
export config
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -31,6 +33,7 @@ type
|
||||||
|
|
||||||
|
|
||||||
proc config*(marketplace: Marketplace): MarketplaceConfig {.contract, view.}
|
proc config*(marketplace: Marketplace): MarketplaceConfig {.contract, view.}
|
||||||
|
proc token*(marketplace: Marketplace): Address {.contract, view.}
|
||||||
proc slashMisses*(marketplace: Marketplace): UInt256 {.contract, view.}
|
proc slashMisses*(marketplace: Marketplace): UInt256 {.contract, view.}
|
||||||
proc slashPercentage*(marketplace: Marketplace): UInt256 {.contract, view.}
|
proc slashPercentage*(marketplace: Marketplace): UInt256 {.contract, view.}
|
||||||
proc minCollateralThreshold*(marketplace: Marketplace): UInt256 {.contract, view.}
|
proc minCollateralThreshold*(marketplace: Marketplace): UInt256 {.contract, view.}
|
||||||
|
|
|
@ -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.}
|
|
|
@ -1,6 +1,7 @@
|
||||||
import pkg/chronos
|
import pkg/chronos
|
||||||
import pkg/upraises
|
import pkg/upraises
|
||||||
import pkg/questionable
|
import pkg/questionable
|
||||||
|
import pkg/ethers/erc20
|
||||||
import ./contracts/requests
|
import ./contracts/requests
|
||||||
import ./clock
|
import ./clock
|
||||||
|
|
||||||
|
@ -18,6 +19,10 @@ type
|
||||||
OnRequestCancelled* = proc(requestId: RequestId) {.gcsafe, upraises:[].}
|
OnRequestCancelled* = proc(requestId: RequestId) {.gcsafe, upraises:[].}
|
||||||
OnRequestFailed* = 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.} =
|
method getSigner*(market: Market): Future[Address] {.base, async.} =
|
||||||
raiseAssert("not implemented")
|
raiseAssert("not implemented")
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ method enterAsync(state: PurchasePending) {.async.} =
|
||||||
raiseAssert "invalid state"
|
raiseAssert "invalid state"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
await purchase.market.approveFunds(request.price())
|
||||||
await purchase.market.requestStorage(request)
|
await purchase.market.requestStorage(request)
|
||||||
except CatchableError as error:
|
except CatchableError as error:
|
||||||
state.switch(PurchaseErrored(error: error))
|
state.switch(PurchaseErrored(error: error))
|
||||||
|
|
|
@ -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=<account>`, where `account` can be one following:
|
Optionally, if you want to use the Marketplace blockchain functionality, you need to also include these flags: `--persistence --eth-account=<account>`, where `account` can be one following:
|
||||||
|
|
||||||
- `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266`
|
|
||||||
- `0x70997970C51812dc3A010C7d01b50e0d17dc79C8`
|
- `0x70997970C51812dc3A010C7d01b50e0d17dc79C8`
|
||||||
- `0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC`
|
- `0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC`
|
||||||
- `0x90F79bf6EB2c4f870365E785982E1f101E93b906`
|
- `0x90F79bf6EB2c4f870365E785982E1f101E93b906`
|
||||||
|
- `0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65`
|
||||||
|
|
||||||
**For each node use a different account!**
|
**For each node use a different account!**
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,9 @@ proc new*(_: type MockMarket): MockMarket =
|
||||||
)
|
)
|
||||||
MockMarket(signer: Address.example, config: config)
|
MockMarket(signer: Address.example, config: config)
|
||||||
|
|
||||||
|
method approveFunds*(market: MockMarket, amount: UInt256) {.async.} =
|
||||||
|
discard
|
||||||
|
|
||||||
method getSigner*(market: MockMarket): Future[Address] {.async.} =
|
method getSigner*(market: MockMarket): Future[Address] {.async.} =
|
||||||
return market.signer
|
return market.signer
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import pkg/chronos
|
import pkg/chronos
|
||||||
import pkg/stint
|
import pkg/stint
|
||||||
import codex/contracts
|
import codex/contracts
|
||||||
import codex/contracts/testtoken
|
import ./token
|
||||||
import ../ethertest
|
import ../ethertest
|
||||||
|
|
||||||
ethersuite "Collateral":
|
ethersuite "Collateral":
|
||||||
|
|
|
@ -2,11 +2,11 @@ import std/json
|
||||||
import pkg/chronos
|
import pkg/chronos
|
||||||
import pkg/ethers/testing
|
import pkg/ethers/testing
|
||||||
import codex/contracts
|
import codex/contracts
|
||||||
import codex/contracts/testtoken
|
|
||||||
import codex/storageproofs
|
import codex/storageproofs
|
||||||
import ../ethertest
|
import ../ethertest
|
||||||
import ./examples
|
import ./examples
|
||||||
import ./time
|
import ./time
|
||||||
|
import ./token
|
||||||
|
|
||||||
ethersuite "Marketplace contracts":
|
ethersuite "Marketplace contracts":
|
||||||
let proof = exampleProof()
|
let proof = exampleProof()
|
||||||
|
|
|
@ -2,11 +2,11 @@ import std/options
|
||||||
import pkg/chronos
|
import pkg/chronos
|
||||||
import pkg/stew/byteutils
|
import pkg/stew/byteutils
|
||||||
import codex/contracts
|
import codex/contracts
|
||||||
import codex/contracts/testtoken
|
|
||||||
import codex/storageproofs
|
import codex/storageproofs
|
||||||
import ../ethertest
|
import ../ethertest
|
||||||
import ./examples
|
import ./examples
|
||||||
import ./time
|
import ./time
|
||||||
|
import ./token
|
||||||
|
|
||||||
ethersuite "On-Chain Market":
|
ethersuite "On-Chain Market":
|
||||||
let proof = exampleProof()
|
let proof = exampleProof()
|
||||||
|
|
|
@ -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.}
|
|
@ -1,5 +1,6 @@
|
||||||
|
import pkg/ethers/erc20
|
||||||
import codex/contracts
|
import codex/contracts
|
||||||
import codex/contracts/testtoken
|
import ../contracts/token
|
||||||
|
|
||||||
proc mint*(signer: Signer, amount = 1_000_000.u256) {.async.} =
|
proc mint*(signer: Signer, amount = 1_000_000.u256) {.async.} =
|
||||||
## Mints a considerable amount of tokens and approves them for transfer to
|
## 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 token = TestToken.new(!deployment().address(TestToken), signer)
|
||||||
let marketplace = Marketplace.new(!deployment().address(Marketplace), signer)
|
let marketplace = Marketplace.new(!deployment().address(Marketplace), signer)
|
||||||
await token.mint(await signer.getAddress(), amount)
|
await token.mint(await signer.getAddress(), amount)
|
||||||
await token.approve(marketplace.address, amount)
|
|
||||||
|
|
||||||
proc deposit*(signer: Signer) {.async.} =
|
proc deposit*(signer: Signer) {.async.} =
|
||||||
## Deposits sufficient collateral into the Marketplace contract.
|
## Deposits sufficient collateral into the Marketplace contract.
|
||||||
let marketplace = Marketplace.new(!deployment().address(Marketplace), signer)
|
let marketplace = Marketplace.new(!deployment().address(Marketplace), signer)
|
||||||
let config = await marketplace.config()
|
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)
|
await marketplace.deposit(config.collateral.initialAmount)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 577e02b8a25198d6897c1f4871b5fd8e1f859e5a
|
Subproject commit 3c12a65769b9a223028df25f78abb6dde06fef35
|
Loading…
Reference in New Issue