diff --git a/codex/contracts/market.nim b/codex/contracts/market.nim index a755c4a6..69100145 100644 --- a/codex/contracts/market.nim +++ b/codex/contracts/market.nim @@ -22,6 +22,7 @@ type signer: Signer configuration: MarketplaceConfig requestCache: LruCache[string, StorageRequest] + allowanceLock: AsyncLock MarketSubscription = market.Subscription EventSubscription = ethers.Subscription @@ -75,6 +76,18 @@ template convertEthersError(msg: string = "", body) = except EthersError as error: raiseMarketError(error.msgDetail.prefixWith(msg)) +template withAllowanceLock*(market: OnChainMarket, body: untyped) = + if market.allowanceLock.isNil: + market.allowanceLock = newAsyncLock() + await market.allowanceLock.acquire() + try: + body + finally: + try: + market.allowanceLock.release() + except AsyncLockError as error: + raise newException(Defect, error.msg, error) + proc approveFunds( market: OnChainMarket, amount: UInt256 ) {.async: (raises: [CancelledError, MarketError]).} = @@ -82,7 +95,11 @@ proc approveFunds( convertEthersError("Failed to approve funds"): let tokenAddress = await market.contract.token() let token = Erc20Token.new(tokenAddress, market.signer) - discard await token.increaseAllowance(market.contract.address(), amount).confirm(1) + let owner = await market.signer.getAddress() + let spender = market.contract.address + market.withAllowanceLock: + let allowance = await token.allowance(owner, spender) + discard await token.approve(spender, allowance + amount).confirm(1) method getSigner*( market: OnChainMarket