nim-ethers/testmodule/testErc20.nim

126 lines
4.7 KiB
Nim
Raw Normal View History

fix: modify unsubscribe cleanup routine and tests (#84) * fix: modify unsubscribe cleanup routine Ignore exceptions (other than CancelledError) if uninstallation of the filter fails. If it's the last step in the subscription cleanup, then filter changes for this filter will no longer be polled so if the filter continues to live on in geth for whatever reason, then it doesn't matter. This includes a number of fixes: - `CancelledError` is now caught inside of `getChanges`. This was causing conditions during `subscriptions.close`, where the `CancelledError` would get consumed by the `except CatchableError`, if there was an ongoing `poll` happening at the time of close. - After creating a new filter inside of `getChanges`, the new filter is polled for changes before returning. - `getChanges` also does not swallow `CatchableError` by returning an empty array, and instead re-raises the error if it is not `filter not found`. - The tests were simplified by accessing the private fields of `PollingSubscriptions`. That way, there wasn't a race condition for the `newFilterId` counter inside of the mock. - The `MockRpcHttpServer` was simplified by keeping track of the active filters only, and invalidation simply removes the filter. The tests then only needed to rely on the fact that the filter id changed in the mapping. - Because of the above changes, we no longer needed to sleep inside of the tests, so the sleeps were removed, and the polling interval could be changed to 1ms, which not only makes the tests faster, but would further highlight any race conditions if present. * docs: rpc custom port documentation --------- Co-authored-by: Adam Uhlíř <adam@uhlir.dev>
2024-10-25 03:58:45 +00:00
import std/os
import pkg/serde
import pkg/asynctest
import pkg/questionable
import pkg/stint
import pkg/ethers
import pkg/ethers/erc20
import ./hardhat
type
TestToken = ref object of Erc20Token
method mint(token: TestToken, holder: Address, amount: UInt256): Confirmable {.base, contract.}
fix: modify unsubscribe cleanup routine and tests (#84) * fix: modify unsubscribe cleanup routine Ignore exceptions (other than CancelledError) if uninstallation of the filter fails. If it's the last step in the subscription cleanup, then filter changes for this filter will no longer be polled so if the filter continues to live on in geth for whatever reason, then it doesn't matter. This includes a number of fixes: - `CancelledError` is now caught inside of `getChanges`. This was causing conditions during `subscriptions.close`, where the `CancelledError` would get consumed by the `except CatchableError`, if there was an ongoing `poll` happening at the time of close. - After creating a new filter inside of `getChanges`, the new filter is polled for changes before returning. - `getChanges` also does not swallow `CatchableError` by returning an empty array, and instead re-raises the error if it is not `filter not found`. - The tests were simplified by accessing the private fields of `PollingSubscriptions`. That way, there wasn't a race condition for the `newFilterId` counter inside of the mock. - The `MockRpcHttpServer` was simplified by keeping track of the active filters only, and invalidation simply removes the filter. The tests then only needed to rely on the fact that the filter id changed in the mapping. - Because of the above changes, we no longer needed to sleep inside of the tests, so the sleeps were removed, and the polling interval could be changed to 1ms, which not only makes the tests faster, but would further highlight any race conditions if present. * docs: rpc custom port documentation --------- Co-authored-by: Adam Uhlíř <adam@uhlir.dev>
2024-10-25 03:58:45 +00:00
let providerUrl = getEnv("ETHERS_TEST_PROVIDER", "localhost:8545")
for url in ["ws://" & providerUrl, "http://" & providerUrl]:
2023-06-27 13:59:31 +00:00
suite "ERC20 (" & url & ")":
2023-06-29 08:23:14 +00:00
var token: Erc20Token
2023-06-27 13:59:31 +00:00
var testToken: TestToken
var provider: JsonRpcProvider
var snapshot: JsonNode
var accounts: seq[Address]
2023-06-27 13:59:31 +00:00
setup:
provider = JsonRpcProvider.new(url, pollingInterval = 100.millis)
snapshot = await provider.send("evm_snapshot")
accounts = await provider.listAccounts()
let deployment = readDeployment()
testToken = TestToken.new(!deployment.address(TestToken), provider.getSigner())
token = Erc20Token.new(!deployment.address(TestToken), provider.getSigner())
2023-06-27 13:59:31 +00:00
teardown:
discard await provider.send("evm_revert", @[snapshot])
await provider.close()
2023-06-27 13:59:31 +00:00
test "retrieves basic information":
check (await token.name()) == "TestToken"
check (await token.symbol()) == "TST"
check (await token.decimals()) == 12
check (await token.totalSupply()) == 0.u256
check (await token.balanceOf(accounts[0])) == 0.u256
check (await token.allowance(accounts[0], accounts[1])) == 0.u256
2023-06-27 13:59:31 +00:00
test "transfer tokens":
check (await token.balanceOf(accounts[0])) == 0.u256
check (await token.allowance(accounts[0], accounts[1])) == 0.u256
2023-06-27 13:59:31 +00:00
discard await testToken.mint(accounts[0], 100.u256)
2023-06-27 13:59:31 +00:00
check (await token.totalSupply()) == 100.u256
check (await token.balanceOf(accounts[0])) == 100.u256
check (await token.balanceOf(accounts[1])) == 0.u256
discard await token.transfer(accounts[1], 50.u256)
2023-06-27 13:59:31 +00:00
check (await token.balanceOf(accounts[0])) == 50.u256
check (await token.balanceOf(accounts[1])) == 50.u256
2023-06-27 13:59:31 +00:00
test "approve tokens":
discard await testToken.mint(accounts[0], 100.u256)
2023-06-27 13:59:31 +00:00
check (await token.allowance(accounts[0], accounts[1])) == 0.u256
check (await token.balanceOf(accounts[0])) == 100.u256
check (await token.balanceOf(accounts[1])) == 0.u256
discard await token.approve(accounts[1], 50.u256)
2023-06-27 13:59:31 +00:00
check (await token.allowance(accounts[0], accounts[1])) == 50.u256
check (await token.balanceOf(accounts[0])) == 100.u256
check (await token.balanceOf(accounts[1])) == 0.u256
2023-10-16 08:23:58 +00:00
test "increase/decrease allowance":
discard await testToken.mint(accounts[0], 100.u256)
check (await token.allowance(accounts[0], accounts[1])) == 0.u256
check (await token.balanceOf(accounts[0])) == 100.u256
check (await token.balanceOf(accounts[1])) == 0.u256
discard await token.increaseAllowance(accounts[1], 50.u256)
check (await token.allowance(accounts[0], accounts[1])) == 50.u256
check (await token.balanceOf(accounts[0])) == 100.u256
check (await token.balanceOf(accounts[1])) == 0.u256
discard await token.increaseAllowance(accounts[1], 50.u256)
check (await token.allowance(accounts[0], accounts[1])) == 100.u256
check (await token.balanceOf(accounts[0])) == 100.u256
check (await token.balanceOf(accounts[1])) == 0.u256
discard await token.decreaseAllowance(accounts[1], 50.u256)
check (await token.allowance(accounts[0], accounts[1])) == 50.u256
check (await token.balanceOf(accounts[0])) == 100.u256
check (await token.balanceOf(accounts[1])) == 0.u256
2023-06-27 13:59:31 +00:00
test "transferFrom tokens":
let senderAccount = accounts[0]
let receiverAccount = accounts[1]
let receiverAccountSigner = provider.getSigner(receiverAccount)
2023-06-27 13:59:31 +00:00
check (await token.balanceOf(senderAccount)) == 0.u256
check (await token.allowance(senderAccount, receiverAccount)) == 0.u256
2023-06-27 13:59:31 +00:00
discard await testToken.mint(senderAccount, 100.u256)
2023-06-27 13:59:31 +00:00
check (await token.totalSupply()) == 100.u256
check (await token.balanceOf(senderAccount)) == 100.u256
check (await token.balanceOf(receiverAccount)) == 0.u256
discard await token.approve(receiverAccount, 50.u256)
2023-06-27 13:59:31 +00:00
check (await token.allowance(senderAccount, receiverAccount)) == 50.u256
check (await token.balanceOf(senderAccount)) == 100.u256
check (await token.balanceOf(receiverAccount)) == 0.u256
discard await token.connect(receiverAccountSigner).transferFrom(senderAccount, receiverAccount, 50.u256)
2023-06-27 13:59:31 +00:00
check (await token.balanceOf(senderAccount)) == 50.u256
check (await token.balanceOf(receiverAccount)) == 50.u256
check (await token.allowance(senderAccount, receiverAccount)) == 0.u256