ERCx
  • ERCx
    • ERCx Overview
    • ERCx Test suites
    • ERCx Interfaces
    • ERCx Token database
  • 🔗Links
    • ERCx Website
    • ERCx Telegram bot
    • Join our Discord!
Powered by GitBook
On this page
  • Details of the test levels
  • Outcomes of test results
  • Specifications of property tests
  • ERC-20 test suite
  • ERC-721 test suite
  • ERC-1155 test suite
  • ERC-4626 test suite
  1. ERCx

ERCx Test suites

What's being tested in ERCx

PreviousERCx OverviewNextERCx Interfaces

Last updated 1 year ago

Details of the test levels

ERCx runs property tests. The properties and the corresponding tests are described in the tables below. Each test has its own row, indicating the conformance level of that test (ABI, Minimal, Recommended, and Desirable) the name of that test (as displayed in the report) and an informal description of the property being tested. Test levels are understood as follows.

  • Tests of level ABI (Signature) check the signatures (i.e., name, inputs, and outputs) of the token functions/events.

  • Tests of level Standard check obligations and recommendations from the standard, i.e., the properties that contain the keywords MUST and SHOULD respectively, but also any property stated in the respective EIP specification.

  • Tests of level Security check properties we deem important to the sane functioning of a token and complement the standard specification. Some of these properties were violated in ERC-20 hacks. Some othesr consider additional functions not in the standard. Examples of security properties include (i) self-transferring tokens is allowed but must not modify the balance (ii) increase of allowance should rely on an increaseAllowance function.

  • Tests of level Features check feature properties of the contract; these are neither desirable nor undesirable properties but indicate implementation choices of the contract. Examples of fingerprint properties include the infinite approval property; which holds if once the approval is set to type(uint256).max, it is not decreased by transferFrom operations.

Outcomes of test results

  • Pass: The token has passed the check as stated in the property description.

  • Fail: The token has failed the check as stated in the property description. To know more about the possible reason/s of the failed test, you can simply click on the failed test's feedback description and find out more from the json output displayed. Fields such as reason, decoded_logs could provide more insights to why the test failed. Some possible reasons that you could see are:

    • stdStorage find(StdStorage): Slot(s) not found. - There are some inaccessibility issues with the storage slots of the token and as a result, we are unable to initialize tokens to the intended dummy users.

    • EvmError: Revert - Some functions reverted when called during the execution of the test suite.

    • Any other reasons, e.g., Error: Assertion Failed - The token indeed does not satisfy all these properties OR there are some issues with the token's transfer or minting function which result in insufficient tokens to test the intended property.

    However, if the test failed unexpectedly, i.e., false negative, please so that we can resolve the issue ASAP.

  • Inconclusive: A test is inconclusive if EITHER (a) it is an ABI test of an optional function OR (b) its result is inconclusive as certain conditions are not met while testing the said property test. Some possible reasons for a test to be inconclusive are failure to deal tokens to dummy users before running the test and failure to call the required function before making the property check especially in cases where large values of inputs are used in the test. Note that inconclusive tests from non-ABI levels are still important property tests that a token should satisfy. Thus, it is essential to manually check whether the token satisfies those properties. If the reason The 'vm.assume' cheatcode rejected too many inputs (65536 allowed) is shown in the reason field, then the test is considered as inconclusive as the test suite cannot generate sufficient appropriate inputs required to satisfy the assumptions in the test.

Specifications of property tests

In the below description of properties, we use the following terminology:

  • tokenSender: address that sends tokens (usually in a transaction);

  • tokenReceiver: address that receives tokens (usually in a transaction);

  • tokenApprover: address that approves tokens (usually in an approval);

  • tokenApprovee: address that tokenApprover approves (usually in an approval).

ERC-20 test suite

PROPERTY
TEST NAME

The allowance(address,address) function conforms to the EIP-20 standard.

testAllowanceAbi

The allowance(address,address) function is present in the contract.

testAllowanceSignature

The Approval(address,address,uint256) event is present in the contract.

testApprovalEventSignature

The approve(address,uint256) function conforms to the EIP-20 standard.

testApproveAbi

The approve(address,uint256) function is present in the contract.

testApproveSignature

The balanceOf(address) function conforms to the EIP-20 standard.

testBalanceOfAbi

The balanceOf(address) function is present in the contract.

testBalanceOfSignature

The decimals() function conforms to the EIP-20 standard.

testDecimalsAbi

The decimals() function is present in the contract.

testDecimalsSignature

The name() function conforms to the EIP-20 standard.

testNameAbi

The name() function is present in the contract.

testNameSignature

The symbol() function conforms to the EIP-20 standard.

testSymbolAbi

The symbol() function is present in the contract.

testSymbolSignature

The totalSupply() function conforms to the EIP-20 standard.

testTotalSupplyAbi

The totalSupply() function is present in the contract.

testTotalSupplySignature

The transfer(address,uint256) function conforms to the EIP-20 standard.

testTransferAbi

The Transfer(address,address,uint256) event is present in the contract.

testTransferEventSignature

The transferFrom(address,address,uint256) function conforms to the EIP-20 standard.

testTransferFromAbi

The transferFrom(address,address,uint256) function is present in the contract.

testTransferFromSignature

The transfer(address,uint256) function is present in the contract.

testTransferSignature

The increaseAllowance(address,uint256) function is present in the contract.

testIncreaseAllowanceSignature

The increaseAllowance(address,uint256) function conforms to the EIP-20 standard.

testIncreaseAllowanceAbi

The decreaseAllowance(address,uint256) function is present in the contract.

testDecreaseAllowanceSignature

The decreaseAllowance(address,uint256) function conforms to the EIP-20 standard.

testDecreaseAllowanceAbi

The pause() function is present in the contract.

testPauseSignature

The pause() function conforms to the EIP-20 standard.

testPauseAbi

The burn(uint256) function is present in the contract.

testBurnUint256Signature

The burn(uint256) function conforms to the EIP-20 standard.

testBurnUint256Abi

The burnToken(uint256) function is present in the contract.

testBurnTokenUint256Signature

The burnToken(uint256) function conforms to the EIP-20 standard.

testBurnTokenUint256Abi

The burn(address,uint256) function is present in the contract.

testBurnAddressUint256Signature

The burn(address,uint256) function conforms to the EIP-20 standard.

testBurnAddressUint256Abi

The burnToken(address,uint256) function is present in the contract.

testBurnTokenAddressUint256Signature

The burnToken(address,uint256) function conforms to the EIP-20 standard.

testBurnTokenAddressUint256Abi

The burnFrom(address,uint256) function is present in the contract.

testBurnFromAddressUint256Signature

The burnFrom(address,uint256) function conforms to the EIP-20 standard.

testBurnFromAddressUint256Abi

The mint(address,uint256) function is present in the contract.

testMintSignature

The mint(address,uint256) function conforms to the EIP-20 standard.

testMintAbi

The mintToken(address,uint256) function is present in the contract.

testMintTokenSignature

The mintToken(address,uint256) function conforms to the EIP-20 standard.

testMintTokenAbi

The issue(address,uint256) function is present in the contract.

testIssueSignature

The issue(address,uint256) function conforms to the EIP-20 standard.

testIssueAbi

The enableTokenTransfer() function is present in the contract.

testEnableTokenTransferSignature

The enableTokenTransfer() function conforms to the EIP-20 standard.

testEnableTokenTransferAbi

The disableTokenTransfer() function is present in the contract.

testDisableTokenTransferSignature

The disableTokenTransfer() function conforms to the EIP-20 standard.

testDisableTokenTransferAbi

The owned() function is present in the contract.

testOwnedSignature

The owned() function conforms to the EIP-20 standard.

testOwnedAbi

The setOwner(address) function is present in the contract.

testSetOwnerSignature

The setOwner(address) function conforms to the EIP-20 standard.

testSetOwnerAbi

The batchTransfer(address[],uint256) function is present in the contract.

testBatchTransferSignature

The batchTransfer(address[],uint256) function conforms to the EIP-20 standard.

testBatchTransferAbi

The sell(uint256) function is present in the contract.

testSellSignature

The sell(uint256) function conforms to the EIP-20 standard.

testSellAbi

The setPrices(uint256,uint256) function is present in the contract.

testSetPricesSignature

The setPrices(uint256,uint256) function conforms to the EIP-20 standard.

testSetPricesAbi

PROPERTY
TEST NAME

A tokenReceiver SHOULD NOT be able to call transferFrom of an amount more than her allowance from the tokenSender even if the tokenSender's balance is more than or equal to the said amount.

testCannotTransferFromMoreThanAllowanceLowerThanBalance

A tokenReceiver SHOULD NOT be able to call transferFrom of an amount more than the tokenSender's balance even if the tokenReceiver's allowance from the tokenSender is less than the said amount.

testCannotTransferFromMoreThanBalanceButLowerThanAllowance

A tokenSender (which is also the msg.sender) SHOULD NOT be able to call transfer of an amount more than his balance.

testCannotTransferMoreThanBalance

A tokenReceiver SHOULD NOT be able to call transferFrom of any positive amount from a tokenSender if the tokenSender did not approve the tokenReceiver previously.

testNoApprovalCannotTransferFrom

A msg.sender SHOULD NOT be able to call transferFrom of any positive amount from his/her own acount to any tokenReceiver if the msg.sender did not approve him/herself prior to the call.

testNoSelfApprovalCannotSelfTransferFrom

A successful approve call of positive amount MUST emit the Approval event correctly.

testPositiveApprovalEventEmission

After a tokenApprover approves a tokenApprovee some positive amount via an approve call, any positive amount up to the said amount MUST be transferable by tokenApprovee via a transferFrom call, provided a sufficient balance of tokenApprover.

testPositiveApproveAllowsPositiveTransferFrom

After a tokenApprover approves a tokenApprovee some positive amount via an approve call, zero amount MUST be transferable by tokenApprovee via a transferFrom call, provided a sufficient balance of tokenApprover.

testPositiveApproveAllowsZeroTransferFrom

Positive approved amount MUST be reflected in the allowance correctly.

testPositiveApproveLeadsToAllowance

A successful transfer call of positive amount MUST emit the Transfer event correctly.

testPositiveTransferEventEmission

A successful transferFrom call of positive amount MUST emit Transfer event correctly.

testPositiveTransferFromEventEmission

A successful approve call of zero amount MUST emit the Approval event correctly.

testZeroApprovalEventEmission

Zero approved amount MUST be reflected in the allowance correctly.

testZeroApproveLeadsToAllowance

A successful transferFrom of zero amount by any user other than the tokenSender, from and to different accounts, MUST emit a Transfer event correctly.

testZeroTransferFromByOtherEmitsEvent

A successful transferFrom call of zero amount by any user other than the tokenSender MUST be possible, from and to the same account.

testZeroTransferFromByOtherFromAndToSameAccountPossible

A successful transferFrom call of zero amount by any user other than the tokenSender MUST be possible, from and to different accounts.

testZeroTransferFromByOtherPossibleFromAndToDifferentAccounts

A successful transferFrom of zero amount by any user other than the tokenSender, from and to the same address, MUST emit a Transfer event correctly.

testZeroTransferFromByOtherToSameAccountEmitsEvent

A successful transferFrom call of zero amount by any user other than the tokenSender to the tokenSender MUST be possible.

testZeroTransferFromByOtherToSelfPossible

A successful transferFrom call of zero amount by the tokenSender herself MUST be possible.

testZeroTransferFromBySelfPossible

A successful transferFrom call of zero amount by the tokenSender herself to herself MUST emit a Transfer event correctly.

testZeroTransferFromBySelfToSelfEmitsEvent

A successful transferFrom call of zero amount by the tokenSender herself to someone MUST emit a Transfer event correctly.

testZeroTransferFromBySelfToSomeoneEmitsEvent

A successful transfer call of zero amount to another account MUST emit the Transfer event correctly.

testZeroTransferToOthersEmitsEvent

A successful transfer call of zero amount to another account MUST be possible.

testZeroTransferToOthersPossible

A successful transfer call of zero amount to self MUST emit the Transfer event correctly.

testZeroTransferToSelfEmitsEvent

A successful transfer call of zero amount to self MUST be possible.

testZeroTransferToSelfPossible

PROPERTY
TEST NAME

The zero address SHOULD NOT have any token from the contract.

testAddressZeroHasNoToken

Contract owner cannot control balance by using minting overflow (via mint(address,uint256) or mintToken(address,uint256) or issue(address,uint256)).

testBalanceDoesNotOverflowByMinting

A msg.sender SHOULD be able to retrieve his/her own balance.

testBalanceOfCaller

A msg.sender SHOULD be able to retrieve balance of an address different from his/hers.

testBalanceOfNonCaller

batchTransfer from a tokenSender to multiple tokenReceivers reverts when there is an overflow of the total amount transferred, i.e., amount * tokenReceivers.length is above MAX_UINT256.

testBatchTransferDoesNotOverflow

batchTransfer from the contractOwner to multiple tokenReceivers does not overflow when the total amount transferred is above MAX_UINT256.

testBatchTransferDoesNotOverflowByContractOwner

Allowance should be updated correctly after burning (via burnFrom(address,uint256) or burnToken(address,uint256) or burn(address,uint256)).

testBurningFromUpdatesAllowance

User balance should be updated correctly after burning (via burnFrom(address,uint256) or burnToken(address,uint256) or burn(address,uint256)). The balance of the tokenApprover is decreased by the burned amount. The balance of the tokenApprovee (performing the burn) is let unchanged.

testBurningFromUpdatesBalance

Total supply should be updated correctly after burning (via burnFrom(address,uint256) or burnToken(address,uint256) or burn(address,uint256)).

testBurningFromUpdatesTotalSupply

Allowance should not change after burning zero token (via burnFrom(address,uint256) or burnToken(address,uint256) or burn(address,uint256)).

testBurningFromZeroTokenDoesNotUpdateAllowance

User balance should not change after burning zero token (via burnFrom(address,uint256) or burnToken(address,uint256) or burn(address,uint256)).

testBurningFromZeroTokenDoesNotUpdateBalances

Total supply should not be updated after burning zero token (via burnFrom(address,uint256) or burnToken(address,uint256) or burn(address,uint256)).

testBurningFromZeroTokenDoesNotUpdateTotalSupply

User balance should be updated correctly after burning (via burn(uint256) or burnToken(uint256)).

testBurningUpdatesBalance

Total supply should be updated correctly after burning (via burn(uint256) or burnToken(uint256)).

testBurningUpdatesTotalSupply

User balance should not change when burning zero token (via burn(uint256) or burnToken(uint256)).

testBurningZeroTokenDoesNotUpdateBalance

Total supply should not change after burning zero tokens (via burn(uint256) or burnToken(uint256)).

testBurningZeroTokenDoesNotUpdateTotalSupply

A successful call of approve of any amount to the zero address SHOULD NOT be allowed.

testCannotApprovePositiveAmountToZeroAddress

If consecutive calls of approve function of positive-to-positive amounts can be called, then the allowance is set to the right amount after the second call.

testCorrectOverwriteApprovePositiveToPositive

Consecutive calls of approve function of positive-to-zero amounts CAN be called and the allowance is set to the right amount after the second call.

testCorrectOverwriteApprovePositiveToZero

Consecutive calls of approve function of zero-to-positive amounts CAN be called and the allowance is set to the right amount after the second call.

testCorrectOverwriteApproveZeroToPositive

Consecutive calls of approve function of zero-to-zero amounts CAN be called and the allowance is set to the right amount after the second call.

testCorrectOverwriteApproveZeroToZero

It is possible to deal the intended amount of tokens to dummy users for interacting with the contract.

testDealIntendedTokensToDummyUsers

A successful decreaseAllowance call MUST decrease the allowance of the tokenApprovee correctly.

testDecreaseAllowanceAsExpected

A decreaseAllowance call will REVERT if there's not enough allowance to decrease.

testDecreaseAllowanceBehaviorExact

The decreaseAllowance function DOES NOT ALLOW allowance to be double-spent, i.e., Alice CAN decrease her allowance for Bob by the correct amount even if Bob tries to front-run her by calling transferFrom call right before her call.

testDecreaseAllowanceDoubleSpend

The transferFrom function DOES NOT have the potential to take fees.

testFeeTakingTransferFromPotential

The transferFrom function DOES NOT take fees at test execution time.

testFeeTakingTransferFromPresent

The transfer function DOES NOT have the potential to take fees.

testFeeTakingTransferPotential

The transfer function DOES NOT take fees at test execution time.

testFeeTakingTransferPresent

A successful increaseAllowance call MUST increase the allowance of the tokenApprovee correctly.

testIncreaseAllowanceAsExpected

The increaseAllowance function DOES NOT ALLOW allowance to be double-spent, i.e., Alice CAN increase her allowance for Bob by the correct amount even if Bob tries to front-run her by calling transferFrom call right before her call.

testIncreaseAllowanceDoubleSpend

Minting to the zero address should not be possible (via mint(address,uint256) or mintToken(address,uint256) or issue(address,uint256)). Minting to this address should fail.

testMintingToZeroAddressShouldFail

User balance should be updated correctly after minting (via mint(address,uint256) or mintToken(address,uint256) or issue(address,uint256)).

testMintingUpdatesBalance

Total supply should be updated correctly after minting (via mint(address,uint256) or mintToken(address,uint256) or issue(address,uint256)).

testMintingUpdatesTotalSupply

Minting zero token (via mint(address,uint256) or mintToken(address,uint256) or issue(address,uint256)) should not change the balance of the account target of the mint.

testMintingZeroShouldNotChangeBalance

Minting zero token (via mint(address,uint256) or mintToken(address,uint256) or issue(address,uint256)) should not change the total supply.

testMintingZeroShouldNotChangeTotalSupply

Multiple calls of transferFrom SHOULD NOT be allowed once allowance reach zero even if the tokenSender's balance is more than the allowance.

testMultipleTransferFromCannotExceedAllowance

Contract owner cannot issue random amounts of tokens (via mint(address,uint256) or mintToken(address,uint256) or issue(address,uint256)) by bypassing the check of max minting value using great values.

testNoExcessByMintingViaOverflow

If the contract has a function setOwner(address), an address different from the current contract owner should not be able to call function setOwner(address).

testNonOwnerCannotChangeOwner

If the contract has a walletAddress and an disableTransfer function, an address different from walletAddress can not disable token transfers through function enableTokenTransfer()

testNonWalletAddressCannotDisableTransfer

If the contract has a walletAddress and an enableTransfer function, an address different from walletAddress can not enable token transfers through function enableTokenTransfer()

testNonWalletAddressCannotEnableTransfer

If the contract has a function setOwner(address), the current contract owner should be able to call function setOwner(address).

testOwnerCanChangeOwner

Contract owner cannot control sell price by using overflow.

testOwnerCannotOverflowSellBySettingPrice

After a tokenApprover decreases the allowance of a tokenApprovee by some positive amount via a decreaseAllowance call, any amount up to the decreased allowance MUST be transferable by tokenApprovee, provided a sufficient balance of tokenApprover.

testPositiveDecreaseAllowanceAllowsPositiveTransferFrom

After a tokenApprover decreases the allowance of a tokenApprovee by some positive amount via a decreaseAllowance call, zero amount MUST be transferable by tokenApprovee, provided a sufficient balance of tokenApprover.

testPositiveDecreaseAllowanceAllowsZeroTransferFrom

A successful decreaseAllowance call of positive amount MUST emit the Approval event correctly.

testPositiveDecreaseAllowanceEventEmission

After a tokenApprover increases the allowance of a tokenApprovee by some positive amount via an increaseAllowance call, any amount up to the increased allowance MUST be transferable by tokenApprovee, provided a sufficient balance of tokenApprover.

testPositiveIncreaseAllowanceAllowsPositiveTransferFrom

After a tokenApprover increases the allowance of a tokenApprovee by some positive amount via an increaseAllowance call, zero amount MUST be transferable by tokenApprovee, provided a sufficient balance of tokenApprover.

testPositiveIncreaseAllowanceAllowsZeroTransferFrom

A successful increaseAllowance call of positive amount MUST emit the Approval event correctly.

testPositiveIncreaseAllowanceEventEmission

Multiple transfer calls of positive amounts are ALLOWED given that the sum of the transferred amounts is less than or equal to the tokenSender's balance.

testPositiveMultipleTransfer

Multiple transferFrom calls of positive amounts are ALLOWED given that the sum of the transferred amounts is less than or equal to the tokenSender's balance and approvals are given by the tokenSender.

testPositiveMultipleTransferFrom

Self approval of positive amount is ALLOWED and the allowance is correctly updated.

testPositiveSelfApprove

Self approval and call of transferFrom from its own account of positive amount is ALLOWED.

testPositiveSelfApproveTransferFrom

Self decreaseAllowance call of positive amount is ALLOWED.

testPositiveSelfDecreaseAllowance

Self decreaseAllowance call of positive amount, followed by a transferFrom call of an amount up to the decreased allowance for herself is ALLOWED.

testPositiveSelfDecreaseAllowanceTransferFrom

Self increaseAllowance call of positive amount is ALLOWED.

testPositiveSelfIncreaseAllowance

Self increaseAllowance call, followed by a transferFrom call of some positive amount is ALLOWED.

testPositiveSelfIncreaseAllowanceTransferFrom

Self transfer call of positive amount is ALLOWED and SHOULD NOT modify the balance.

testPositiveSelfTransfer

A tokenReceiver CAN call transferFrom of the tokenSender's total balance amount given that tokenSender has approved that.

testPositiveTotalTransferFromToOther

A msg.sender CAN call transfer of her total balance amount to a tokenReceiver and the balances are modified accordingly.

testPositiveTotalTransferToOther

A transferFrom call of any positive amount to the zero address SHOULD revert.

testPositiveTransferFromToZeroShouldRevert

A transfer call of any positive amount to the zero address SHOULD revert.

testPositiveTransferToZeroShouldRevert

Only contract caller can call function owned() which sets ownership of the contract.

testShouldNotChangeOwnership

The contract's totalSupply variable SHOULD NOT be altered after transfer is called.

testTotalSupplyConstantAfterTransfer

The contract's totalSupply variable SHOULD NOT be altered after transferFrom is called.

testTotalSupplyConstantAfterTransferFrom

The value of variable totalSupply, if it represents the sum of all tokens in the contract should not overflow when the sum of tokens changes via minting (via mint(address,uint256) or mintToken(address,uint256) or issue(address,uint256)).

testTotalSupplyDoesNotOverflowByMinting

Transfer should not be possible when token is paused.

testTransferAreNotPossibleWhenPaused

A successful call of transfer DOES NOT update the balance of users who are neither the tokenSender nor the tokenReceiver.

testTransferDoesNotUpdateOthersBalances

TransferFrom should not be possible when token is paused.

testTransferFromAreNotPossibleWhenPaused

A successful transferFrom of any positive amount MUST decrease the allowance of the tokenSender by the transferred amount.

testTransferFromDecreaseAllowanceAsExpected

A successful call of transferFrom DOES NOT update the balance of users who are neither the tokenSender nor the tokenReceiver.

testTransferFromDoesNotUpdateOthersBalances

If the contract has a walletAddress and an disableTransfer function, address walletAddress can disable token transfers through function enableTokenTransfer()

testWalletAddressCanDisableWalletTransfer

If the contract has a walletAddress and an enableTransfer function, address walletAddress can enable token transfers through function enableTokenTransfer()

testWalletAddressCanEnableWalletTransfer

A approve call of any positive amount SHOULD revert if the tokenSender is the zero address.

testZeroAddressCannotApprovePositiveAmount

A transfer call of any positive amount SHOULD revert if the tokenSender is the zero address.

testZeroAddressCannotTransferPositiveAmount

A successful decreaseAllowance call of zero amount MUST emit the Approval event correctly.

testZeroDecreaseAllowanceEventEmission

A successful increaseAllowance call of zero amount MUST emit the Approval event correctly.

testZeroIncreaseAllowanceEventEmission

Multiple calls of transfer of zero amount are ALLOWED.

testZeroMultipleTransfer

Multiple calls of transferFrom of zero amount are ALLOWED.

testZeroMultipleTransferFrom

Self approval of zero amount is ALLOWED and the allowance is correctly updated.

testZeroSelfApprove

Self approval and call of transferFrom from its own account of zero amount is ALLOWED.

testZeroSelfApproveTransferFrom

Self decreaseAllowance call of zero amount is ALLOWED.

testZeroSelfDecreaseAllowance

Self decreaseAllowance call of zero amount, followed by a transferFrom call of an amount up to the decreased allowance for herself is ALLOWED.

testZeroSelfDecreaseAllowanceTransferFrom

Self increaseAllowance call of zero amount is ALLOWED.

testZeroSelfIncreaseAllowance

Self increaseAllowance call, followed by a transferFrom call of zero amount is ALLOWED.

testZeroSelfIncreaseAllowanceTransferFrom

Self transfer call of zero amount is ALLOWED and SHOULD NOT modify the balance.

testZeroSelfTransfer

A tokenReceiver CAN call transferFrom of the tokenSender's total balance amount of zero.

testZeroTotalTransferFromToOther

A msg.sender CAN call transfer of her total balance of zero to a tokenReceiver and the balances are not modified.

testZeroTotalTransferToOther

A transferFrom call of zero amount to the zero address SHOULD revert.

testZeroTransferFromToZeroShouldRevert

A transfer call of zero amount to the zero address SHOULD revert.

testZeroTransferToZeroShouldRevert

PROPERTY
TEST NAME

The token ALLOWS tokenApprover to call approve of an amount higher than her balance.

testCanApproveMoreThanBalance

A decreaseAllowance call DOES NOT REVERT if there's not enough allowance to decrease and TURNS the allowance to zero since the current allowance is smaller than the amount to decrease.

testDecreaseAllowanceBehaviorInexact

A successful decreaseAllowance call of a positive amount DECREASES the allowance by MORE than the said amount.

testDecreaseAllowanceGtExpected

A successful decreaseAllowance call of a positive amount DECREASES the allowance by LESS than the said amount.

testDecreaseAllowanceLtExpected

A successful increaseAllowance call of a positive amount INCREASES the allowance by MORE than the said amount.

testIncreaseAllowanceGtExpected

A successful increaseAllowance call of a positive amount INCREASES the allowance by LESS than the said amount.

testIncreaseAllowanceLtExpected

The token HAS infinite approval property. That is, if the approval is set to MAX_UINT256 and a transfer is called, the allowance does not decrease by the transferred amount.

testInfiniteApprovalConstant

The token DOES NOT have infinite approval property. That is, if the approval is set to MAX_UINT256 and a transfer is called, the allowance is decreased by the transferred amount.

testInfiniteApprovalNotConstant

Given the token DOES NOT ALLOW tokenApprover to call approve of an amount higher than her balance. The tokenApprover MUST maintain at least the said amount in her balance before she can make a transfer call to an account other than the tokenApprovee.

testMaintainsApprovalLowerThanBalance

Consecutive calls of approve function of positive-to-positive amounts CAN be called.

testOverwriteApprovePositiveToPositive

The token REVERTS if a tokenApprover approves a tokenApprovee more than its balance.

testRevertsIfApprovalGreaterThanBalance

The token REVERTS if one set the approval to MAX_UINT256.

testRevertsOnInfiniteApproval

A successful transferFrom call of a positive amount DECREASES the allowance of the tokenSender by MORE than the transferred amount.

testTransferFromDecreaseAllowanceGtExpected

A successful transferFrom call of a positive amount DECREASES the allowance of the tokenSender by LESS than the transferred amount.

testTransferFromDecreaseAllowanceLtExpected

ERC-721 test suite

PROPERTY
TEST NAME

The balanceOf(address) function is present in the contract.

testBalanceOfSignature

The balanceOf(address) function conforms to the EIP-721 standard.

testBalanceOfAbi

The ownerOf(uint256) function is present in the contract.

testOwnerOfSignature

The ownerOf(uint256) function conforms to the EIP-721 standard.

testOwnerOfAbi

The safeTransferFrom(address,address,uint256,bytes) function is present in the contract.

testSafeTransferFrom4Signature

The safeTransferFrom(address,address,uint256,bytes) function conforms to the EIP-721 standard.

testSafeTransferFrom4Abi

The safeTransferFrom(address,address,uint256) function is present in the contract.

testSafeTransferFrom3Signature

The safeTransferFrom(address,address,uint256) function conforms to the EIP-721 standard.

testSafeTransferFrom3Abi

The transferFrom(address,address,uint256) function is present in the contract.

testTransferFromPayableSignature

The transferFrom(address,address,uint256) function conforms to the EIP-721 standard.

testTransferFromPayableAbi

The approve(address,uint256) function is present in the contract.

testApprovePayableSignature

The approve(address,uint256) function conforms to the EIP-721 standard.

testApprovePayableAbi

The setApprovalForAll(address,bool) function is present in the contract.

testSetApprovalForAllSignature

The setApprovalForAll(address,bool) function conforms to the EIP-721 standard.

testSetApprovalForAllAbi

The getApproved(uint256) function is present in the contract.

testGetApprovedSignature

The getApproved(uint256) function conforms to the EIP-721 standard.

testGetApprovedAbi

The isApprovedForAll(address,address) function is present in the contract.

testIsApprovedForAllSignature

The isApprovedForAll(address,address) function conforms to the EIP-721 standard.

testIsApprovedForAllAbi

The name() function is present in the contract.

testNameSignature

The name() function conforms to the EIP-721 standard.

testNameAbi

The symbol() function is present in the contract.

testSymbolSignature

The symbol() function conforms to the EIP-721 standard.

testSymbolAbi

The tokenURI(uint256) function is present in the contract.

testTokenURISignature

The tokenURI(uint256) function conforms to the EIP-721 standard.

testTokenURIAbi

The totalSupply() function is present in the contract.

testTotalSupplySignature

The totalSupply() function conforms to the EIP-721 standard.

testTotalSupplyAbi

The tokenByIndex(uint256) function is present in the contract.

testTokenByIndexSignature

The tokenByIndex(uint256) function conforms to the EIP-721 standard.

testTokenByIndexAbi

The tokenOfOwnerByIndex(address,uint256) function is present in the contract.

testTokenOfOwnerByIndexSignature

The tokenOfOwnerByIndex(address,uint256) function conforms to the EIP-721 standard.

testTokenOfOwnerByIndexAbi

The Transfer(address,address,uint256) event is present in the contract.

testTransferEventSignature

The Approval(address,address,bool) event is present in the contract.

testApprovalEventSignature

The ApprovalForAll(address,address,bool) event is present in the contract.

testApprovalForAllEventSignature

The supportsInterface(bytes4) function is present in the contract.

testSupportsInterfaceSignature

The supportsInterface(bytes4) function conforms to the EIP-721 standard.

testSupportsInterfaceAbi

PROPERTY
TEST NAME

Function approve(address,uint256) throws if msg.sender is not the token owner. This test assumes the approve function is payable and some ether are sent when calling approve().

testApproveRevertsWhenMsgSenderIsNotOwner

A safeTransferFrom(address,address,uint256) (without data) to an EOA can be initiated by the approved address to some other token receiver.

testApprovedAddressCanSafeTransferFromToEOA

A safeTransferFrom(address,address,uint256) (without data) to an EOA can be initiated by the approved address to self.

testApprovedAddressCanSafeTransferFromToEOAFromToSelf

A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver interface can be initiated by the approved address to some other token receiver.

testApprovedAddressCanSafeTransferFromToReceiver

A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver can be initiated by the approved address to self.

testApprovedAddressCanSafeTransferFromToReceiverFromToSelf

A safeTransferFrom(address,address,uint256,bytes) (with data) to an EOA can be initiated by the approved address to some other token receiver.

testApprovedAddressCanSafeTransferFromWithDataToEOA

A safeTransferFrom(address,address,uint256,bytes) (with data) to an EOA can be initiated by the approved address to self.

testApprovedAddressCanSafeTransferFromWithDataToEOAFromToSelf

A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver interface can be initiated by the approved address to some other token receiver.

testApprovedAddressCanSafeTransferFromWithDataToReceiver

A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver can be initiated by the approved address to self.

testApprovedAddressCanSafeTransferFromWithDataToReceiverFromToSelf

A transferFrom(address,address,uint256) to an EOA can be initiated by the approved address to some other token receiver.

testApprovedAddressCanTransferFromToEOA

A transferFrom(address,address,uint256) to an EOA can be initiated by the approved address to self.

testApprovedAddressCanTransferFromToEOAFromToSelf

A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver interface can be initiated by the approved address to some other token receiver.

testApprovedAddressCanTransferFromToReceiver

A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver can be initiated by the approved address to self.

testApprovedAddressCanTransferFromToReceiverFromToSelf

Function approve(address,uint256) can change the approved address for an NFT.

testApprovesCanChangeApprovedAddress

Function approve(address,uint256) can define no approved address by approving the zero address.

testApprovesCanDefineZeroAddressAsApprovedAddress

Function approve(address,uint256) defines the approved address for an NFT.

testApprovesDefinesApprovedAddress

An operator can set any address as approved address for a token owned by the address which granted the operator.

testCanApproveAnyAddressWhenOperator

Function setApprovalForAll(address,bool) can enable and disable an operator to manage all of msg.sender's assets.

testCanEnableAndDisableSomeOneAsOperator

Function setApprovalForAll(address,bool) MUST allow multiple operators per owner.This test takes quite some time to execute.

testCanEnableSeveralOperators

Function setApprovalForAll(address,bool) can enable an operator to manage all of msg.sender's assets. The operator can transfer all assets of the owner.

testCanEnableSomeOneAsOperator

Event Approval emits when approval is affirmed.

testEventApprovalEmitsWhenApprovedIsAffirmed

Event Approval emits when approval is changed.

testEventApprovalEmitsWhenApprovedIsChanged

Event Approval emits when approval is reaffirmed.

testEventApprovalEmitsWhenApprovedIsReAffirmed

Event ApprovalForAll emits when an operator is disabled.

testEventApprovalForAllEmitsWhenOperatorIsDisabled

Event ApprovalForAll emits when an operator is enabled.

testEventApprovalForAllEmitsWhenOperatorIsEnabled

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address of the token to an EOA.

testEventTransferEmitsWhenSafeTransferFromWithDataByApprovedAddressToEOA

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address of the token to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenSafeTransferFromWithDataByApprovedAddressToReceiver

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256,bytes) (with data) by an operator to an EOA.

testEventTransferEmitsWhenSafeTransferFromWithDataByOperatorToEOA

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256,bytes) (with data) by an operator to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenSafeTransferFromWithDataByOperatorToReceiver

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256,bytes) (with data) by token owner to an EOA.

testEventTransferEmitsWhenSafeTransferFromWithDataByOwnerToEOA

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256,bytes) (with data) by token owner to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenSafeTransferFromWithDataByOwnerToReceiver

Event Transfer emits when ownership of tokens changes with transferFrom(address,address,uint256) by the approved address of the token to an EOA.

testEventTransferEmitsWhenTransferFromByApprovedAddressToEOA

Event Transfer emits when ownership of tokens changes with transferFrom(address,address,uint256) by the approved address of the token to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenTransferFromByApprovedAddressToReceiver

Event Transfer emits when ownership of tokens changes with transferFrom(address,address,uint256) by an operator to an EOA.

testEventTransferEmitsWhenTransferFromByOperatorToEOA

Event Transfer emits when ownership of tokens changes with transferFrom(address,address,uint256) without data by an operator to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenTransferFromByOperatorToReceiver

Event Transfer emits when ownership of tokens changes with transferFrom(address,address,uint256) by token owner to an EOA.

testEventTransferEmitsWhenTransferFromByOwnerToEOA

Event Transfer emits when ownership of tokens changes with transferFrom(address,address,uint256) by token owner to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenTransferFromByOwnerToReceiver

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256) (without data) by the approved address of the token to an EOA.

testEventTransferEmitsWhenTransferFromWithoutDataByApprovedAddressToEOA

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256) (without data) by the approved address of the token to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenTransferFromWithoutDataByApprovedAddressToReceiver

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256) (without data) by an operator to an EOA.

testEventTransferEmitsWhenTransferFromWithoutDataByOperatorToEOA

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256) (without data) by an operator to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenTransferFromWithoutDataByOperatorToReceiver

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256) (without data) by token owner to an EOA.

testEventTransferEmitsWhenTransferFromWithoutDataByOwnerToEOA

Event Transfer emits when ownership of tokens changes with safeTransferFrom(address,address,uint256) (without data) by token owner to a contract implementing the ERC721Receiver interface.

testEventTransferEmitsWhenTransferFromWithoutDataByOwnerToReceiver

Function getApproved(uint256) throws if the parameter is not a valid token id.

testGetApprovedRevertsOnInvalidTokenId

A safeTransferFrom(address,address,uint256) (without data) can be initiated by an operator to an EOA.

testOperatorCanSafeTransferFromToEOA

A safeTransferFrom(address,address,uint256) (without data) can be initiated by an operator to some other token receiver.

testOperatorCanSafeTransferFromToReceiver

A safeTransferFrom(address,address,uint256) (without data) can be initiated by an operator to self.

testOperatorCanSafeTransferFromToSelf

A safeTransferFrom(address,address,uint256,bytes) can be initiated by an operator to an EOA.

testOperatorCanSafeTransferFromWithDataToEOA

A safeTransferFrom(address,address,uint256,bytes) can be initiated by an operator to some other token receiver.

testOperatorCanSafeTransferFromWithDataToReceiver

A safeTransferFrom(address,address,uint256,bytes) can be initiated by an operator to self.

testOperatorCanSafeTransferFromWithDataToSelf

A transferFrom(address,address,uint256) can be initiated by an operator to an EOA.

testOperatorCanTransferFromToEOA

A transferFrom(address,address,uint256) can be initiated by an operator to some other token receiver.

testOperatorCanTransferFromToReceiver

A transferFrom(address,address,uint256) can be initiated by an operator to self.

testOperatorCanTransferFromToSelf

A safeTransferFrom(address,address,uint256) (without data) can be initiated by the token owner to an EOA.

testOwnerCanSafeTransferFromToEOA

A safeTransferFrom(address,address,uint256) (without data) can be initiated by the token owner to a contract implementing the ERC721Receiver interface.

testOwnerCanSafeTransferFromToReceiver

A safeTransferFrom(address,address,uint256,bytes) can be initiated by the token owner to an EOA.

testOwnerCanSafeTransferFromWithDataToEOA

A safeTransferFrom(address,address,uint256,bytes) can be initiated by the token owner to a contract implementing the ERC721Receiver interface.

testOwnerCanSafeTransferFromWithDataToReceiver

A transferFrom(address,address,uint256) can be initiated by the token owner to an EOA.

testOwnerCanTransferFromToEOA

A transferFrom(address,address,uint256) can be initiated by the token owner to a contract implementing the ERC721Receiver interface.

testOwnerCanTransferFromToReceiver

A call ownerOf(tokenId) for a non-owned token must throw.

testOwnerOfThrowsForNotOwnedToken

A successful ownerOf(tokenId) call returns the owner of tokenId correctly after a user is provided this token.

testOwnerOfUpdated

Function getApproved(address) does not throw when queried about a valid token id by anyone.

testQueryApprovedAddressIsPossible

Function balanceOf(address) does not throw when queried about a valid address by anyone.

testQueryBalanceIsPossible

Function isApprovedForAll(address,address) does not throw when queried about whether some address is an operator of some owner address, by anyone. This test excludes the zero address.

testQueryIsApprovedForAllAddressIsPossible

A safeTransferFrom(address,address,uint256) (without data) to an EOA by the owner throws if _from (the first address) is not the token owner.

testRevertsByOwnerWhenOwnerIsNotFromInSafeTransferFromToEOA

A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver interface by the owner throws if _from (the first address) is not the token owner.

testRevertsByOwnerWhenOwnerIsNotFromInSafeTransferFromToReceiver

A safeTransferFrom(address,address,uint256,bytes) (with data) to an EOA by the owner throws if _from (the first address) is not the token owner.

testRevertsByOwnerWhenOwnerIsNotFromInSafeTransferFromWithDataToEOA

A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver interface by the owner throws if _from (the first address) is not the token owner.

testRevertsByOwnerWhenOwnerIsNotFromInSafeTransferFromWithDataToReceiver

A transferFrom(address,address,uint256) to an EOA by the owner throws if _from (the first address) is not the token owner.

testRevertsByOwnerWhenOwnerIsNotFromInTransferFromToEOA

A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver interface by the owner throws if _from (the first address) is not the token owner.

testRevertsByOwnerWhenOwnerIsNotFromInTransferFromToReceiver

A safeTransferFrom(address,address,uint256) (without data) to an EOA by someone throws if _from (the first address) is not the token owner.

testRevertsBySomeoneWhenOwnerIsNotFromInSafeTransferFromToEOA

A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver by someone throws if _from (the first address) is not the token owner.

testRevertsBySomeoneWhenOwnerIsNotFromInSafeTransferFromToReceiver

A safeTransferFrom(address,address,uint256,bytes) (with data) to an EOA by someone throws if _from (the first address) is not the token owner.

testRevertsBySomeoneWhenOwnerIsNotFromInSafeTransferFromWithDataToEOA

A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver by someone throws if _from (the first address) is not the token owner.

testRevertsBySomeoneWhenOwnerIsNotFromInSafeTransferFromWithDataToReceiver

A transferFrom(address,address,uint256) to an EOA by someone throws if _from (the first address) is not the token owner.

testRevertsBySomeoneWhenOwnerIsNotFromInTransferFromToEOA

A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver by someone throws if _from (the first address) is not the token owner.

testRevertsBySomeoneWhenOwnerIsNotFromInTransferFromToReceiver

A safeTransferFrom(address,address,uint256) (without data) to an EOA throws if tokenID (uint256) is not a valid token id.

testRevertsSafeTransferFromToEOAWhenTokenIDIsNotValid

A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver interface throws if tokenID (uint256) is not a valid token id.

testRevertsSafeTransferFromToReceiverWhenTokenIDIsNotValid

A safeTransferFrom(address,address,uint256,bytes) (with data) to an EOA throws if tokenID (uint256) is not a valid token id.

testRevertsSafeTransferFromWithDataToEOAWhenTokenIDIsNotValid

A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver interface throws if tokenID (uint256) is not a valid token id.

testRevertsSafeTransferFromWithDataToReceiverWhenTokenIDIsNotValid

A transferFrom(address,address,uint256) to an EOA throws if tokenID (uint256) is not a valid token id.

testRevertsTransferFromToEOAWhenTokenIDIsNotValid

A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver interface throws if tokenID (uint256) is not a valid token id.

testRevertsTransferFromToReceiverWhenTokenIDIsNotValid

A safeTransferFrom(address,address,uint256) (without data) by the approved address to the zero address throws.

testRevertsWhenApprovedAddressSafeTransferFromToZeroAddress

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to the zero address throws.

testRevertsWhenApprovedAddressSafeTransferFromWithDataToZeroAddress

A transferFrom(address,address,uint256) by the approved address to the zero address throws.

testRevertsWhenApprovedAddressTransferFromToZeroAddress

A safeTransferFrom(address,address,uint256) (without data) by the token owner to the zero address throws.

testRevertsWhenOwnerSafeTransferFromToZeroAddress

A safeTransferFrom(address,address,uint256,bytes) (with data) by the token owner to the zero address throws.

testRevertsWhenOwnerSafeTransferFromWithDataToZeroAddress

A transferFrom(address,address,uint256) by the token owner to the zero address throws.

testRevertsWhenOwnerTransferFromToZeroAddress

A safeTransferFrom(address,address,uint256) (without data) by token owner throws if the recipient does not return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) when calling onERC721Received.

testRevertsWhenSafeTransferFromToRecipientIsIncorrectReceiverByOwner

A safeTransferFrom(address,address,uint256) (without data) by someone throws if the recipient does not return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) when calling onERC721Received.

testRevertsWhenSafeTransferFromToRecipientIsIncorrectReceiverBySomeone

A safeTransferFrom(address,address,uint256,bytes) (with data) by token owner throws if the recipient does not return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) when calling onERC721Received.

testRevertsWhenSafeTransferFromWithDataToRecipientIsIncorrectReceiverByOwner

A safeTransferFrom(address,address,uint256,bytes) (with data) by someone throws if the recipient does not return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) when calling onERC721Received.

testRevertsWhenSafeTransferFromWithDataToRecipientIsIncorrectReceiverBySomeone

A safeTransferFrom(address,address,uint256) (without data) by the operator of the token owner to the zero address throws.

testRevertsWhenSomeoneSafeTransferFromToZeroAddress

A safeTransferFrom(address,address,uint256,bytes) (with data) by the operator of the token owner to the zero address throws.

testRevertsWhenSomeoneSafeTransferFromWithDataToZeroAddress

A transferFrom(address,address,uint256) by the operator of the token owner to the zero address throws.

testRevertsWhenSomeoneTransferFromToZeroAddress

A safeTransferFrom(address,address,uint256) (without data) to an EOA by the approved address correctly resets the approved address for that token.

testSafeTransferFromByApprovedEOAAddressResetsApprovedAddress

A safeTransferFrom(address,address,uint256) (without data) by the approved EOA address to self correctly updates the ownership.

testSafeTransferFromByApprovedEOAAddressToSelfUpdatesOwnership

A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver interface by the approved address correctly resets the approved address for that token.

testSafeTransferFromByApprovedReceiverAddressResetsApprovedAddress

A safeTransferFrom(address,address,uint256) (without data) by the approved Receiver address to self correctly updates the ownership.

testSafeTransferFromByApprovedReceiverAddressToSelfUpdatesOwnership

A safeTransferFrom(address,address,uint256) (without data) by an operator to an EOA correctly updates the ownership.

testSafeTransferFromByOperatorToEOAUpdatesOwnership

A safeTransferFrom(address,address,uint256) (without data) by an operator to some contract implementing the ERC721Receiver interface correctly updates the ownership.

testSafeTransferFromByOperatorToReceiverUpdatesOwnership

A safeTransferFrom(address,address,uint256) (without data) by an operator to self correctly updates the ownership.

testSafeTransferFromByOperatorToSelfUpdatesOwnership

A safeTransferFrom(address,address,uint256) (without data) by the token owner correctly resets the approved address for that token.

testSafeTransferFromByOwnerToEOAResetsApprovedAddress

A safeTransferFrom(address,address,uint256) (without data) by the token owner to an EOA correctly updates the ownership.

testSafeTransferFromByOwnerToEOAUpdatesOwnership

A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver by the token owner correctly resets the approved address for that token.

testSafeTransferFromByOwnerToReceiverResetsApprovedAddress

A safeTransferFrom(address,address,uint256) (without data) by the token owner to a contract implementing the ERC721Receiver correctly updates the ownership.

testSafeTransferFromByOwnerToReceiverUpdatesOwnership

A safeTransferFrom(address,address,uint256) (without data) by an operator correctly resets the approved address for that token.

testSafeTransferFromToEOAByOperatorResetsApprovedAddress

A safeTransferFrom(address,address,uint256) contract implementing the ERC721Receiver interface by an operator correctly resets the approved address for that token.

testSafeTransferFromToReceiverByOperatorResetsApprovedAddress

A safeTransferFrom(address,address,uint256,bytes) (with data) to an EOA by the approved address correctly resets the approved address for that token.

testSafeTransferFromWithDataByApprovedEOAAddressResetsApprovedAddress

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved EOA address to self correctly updates the ownership.

testSafeTransferFromWithDataByApprovedEOAAddressToSelfUpdatesOwnership

A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver interface by the approved address correctly resets the approved address for that token.

testSafeTransferFromWithDataByApprovedReceiverAddressResetsApprovedAddress

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved Receiver address to self correctly updates the ownership.

testSafeTransferFromWithDataByApprovedReceiverAddressToSelfUpdatesOwnership

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to an EOA correctly updates the ownership.

testSafeTransferFromWithDataByOperatorToEOAUpdatesOwnership

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to some contract implementing the ERC721Receiver interface correctly updates the ownership.

testSafeTransferFromWithDataByOperatorToReceiverUpdatesOwnership

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to self correctly updates the ownership.

testSafeTransferFromWithDataByOperatorToSelfUpdatesOwnership

A safeTransferFrom(address,address,uint256,bytes) (with data) by the token owner correctly resets the approved address for that token.

testSafeTransferFromWithDataByOwnerToEOAResetsApprovedAddress

A safeTransferFrom(address,address,uint256,bytes) (with data) by the token owner to an EOA correctly updates the ownership.

testSafeTransferFromWithDataByOwnerToEOAUpdatesOwnership

A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver by the token owner correctly resets the approved address for that token.

testSafeTransferFromWithDataByOwnerToReceiverResetsApprovedAddress

A safeTransferFrom(address,address,uint256,bytes) (with data) by the token owner to a contract implementing the ERC721Receiver correctly updates the ownership.

testSafeTransferFromWithDataByOwnerToReceiverUpdatesOwnership

A safeTransferFrom(address,address,uint256,bytes) (with data) by an operator correctly resets the approved address for that token.

testSafeTransferFromWithDataToEOAByOperatorResetsApprovedAddress

A safeTransferFrom(address,address,uint256,bytes) contract implementing the ERC721Receiver interface by an operator correctly resets the approved address for that token.

testSafeTransferFromWithDataToReceiverByOperatorResetsApprovedAddress

Function balanceOf(address) throws when queried about the zero address.

testThrowsQueryBalanceOfZeroAddress

A transferFrom(address,address,uint256) to an EOA by the approved address correctly resets the approved address for that token.

testTransferFromByApprovedEOAAddressResetsApprovedAddress

A transferFrom(address,address,uint256) by the approved EOA address to self correctly updates the ownership.

testTransferFromByApprovedEOAAddressToSelfUpdatesOwnership

A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver interface by the approved address correctly resets the approved address for that token.

testTransferFromByApprovedReceiverAddressResetsApprovedAddress

A transferFrom(address,address,uint256) by the approved Receiver address to self correctly updates the ownership.

testTransferFromByApprovedReceiverAddressToSelfUpdatesOwnership

A transferFrom(address,address,uint256) by the approved address to an EOA correctly updates the ownership.

testTransferFromByOperatorToEOAUpdatesOwnership

A transferFrom(address,address,uint256) by the approved address to some contract implementing the ERC721Receiver interface correctly updates the ownership.

testTransferFromByOperatorToReceiverUpdatesOwnership

A transferFrom(address,address,uint256) by the approved address to self correctly updates the ownership.

testTransferFromByOperatorToSelfUpdatesOwnership

A transferFrom(address,address,uint256) by the token owner correctly resets the approved address for that token.

testTransferFromByOwnerToEOAResetsApprovedAddress

A transferFrom(address,address,uint256) by the token owner to an EOA correctly updates the ownership.

testTransferFromByOwnerToEOAUpdatesOwnership

A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver by the token owner correctly resets the approved address for that token.

testTransferFromByOwnerToReceiverResetsApprovedAddress

A transferFrom(address,address,uint256) by the token owner to a contract implementing the ERC721Receiver correctly updates the ownership.

testTransferFromByOwnerToReceiverUpdatesOwnership

A transferFrom(address,address,uint256) by an operator correctly resets the approved address for that token.

testTransferFromToEOAByOperatorResetsApprovedAddress

A transferFrom(address,address,uint256) contract implementing the ERC721Receiver interface by an operator correctly resets the approved address for that token.

testTransferFromToReceiverByOperatorResetsApprovedAddress

A successful balanceOf(account) returns the updated balance of an account correctly when the user receives some tokens.

testUserBalanceCorrectAfterReceivingSeveralTokens

A successful balanceOf(account) call MUST return the updated balance of an account correctly when it gets updated with a new token.

testUserBalanceIncrementedAfterReceivingAnOwnedToken

A successful balanceOf(account) call returns 0 for users without tokens.This test may fail in case Bob is an addressed used in this contract.

testUserBalanceInitializedToZero

If the zero address is the approved address, then one cannot transfer token to self if not an operator.

testWhenZeroAddressIsApprovedOneCannotTransferToSelfIfNotOperator

If the zero address is the approved address, then the operator can transfer the token.

testWhenZeroAddressIsApprovedOperatorCanTransfer

If the zero address is the approved address, then the token owner can transfer the token.

testWhenZeroAddressIsApprovedTokenOwnerCanTransfer

PROPERTY
TEST NAME

A transferFrom(address,address,uint256) by token owner throws if the recipient does not return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) when calling onERC721Received.

testRevertsWhenTransferFromToRecipientIsIncorrectReceiverByOwner

A transferFrom(address,address,uint256) by someone throws if the recipient does not return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) when calling onERC721Received.

testRevertsWhenTransferFromToRecipientIsIncorrectReceiverBySomeone

A safeTransferFrom(address,address,uint256) (without data) by the approved address to some EOA correctly updates the balances.

testSafeTransferFromByApprovedAddressToEOAUpdatesBalances

A safeTransferFrom(address,address,uint256) (without data) by the approved address to the contract owner does not update his balance.

testSafeTransferFromByApprovedAddressToOwnerDoesNotUpdatesBalance

A safeTransferFrom(address,address,uint256) (without data) by the approved address to some other contract implementing the ERC721Receiver correctly updates the balances.

testSafeTransferFromByApprovedAddressToReceiverUpdatesBalances

A safeTransferFrom(address,address,uint256) (without data) by the approved EOA address to self correctly updates the balances.

testSafeTransferFromByApprovedEOAAddressToSelfUpdatesBalances

A safeTransferFrom(address,address,uint256) (without data) by the approved ERC721Receiver address to self correctly updates the balances.

testSafeTransferFromByApprovedReceiverAddressToSelfUpdatesBalances

A safeTransferFrom(address,address,uint256) (without data) by an EOA to himself does not update his balance.

testSafeTransferFromByEOAOwnerToHimSelfDoesNotUpdatesBalance

A safeTransferFrom(address,address,uint256) (without data) by the approved address to an EOA correctly updates the balances.

testSafeTransferFromByOperatorToEOAUpdatesBalances

A safeTransferFrom(address,address,uint256) (without data) by the approved address to some other token receiver correctly updates the balances.

testSafeTransferFromByOperatorToReceiverUpdatesBalances

A safeTransferFrom(address,address,uint256) (without data) by the approved address to self correctly updates the balances.

testSafeTransferFromByOperatorToSelfUpdatesBalances

A safeTransferFrom(address,address,uint256) (without data) by an ERC721Receiver to himself does not update his balance.

testSafeTransferFromByReceiverOwnerToHimSelfDoesNotUpdatesBalance

A safeTransferFrom(address,address,uint256) (without data) to an EOA by the owner correctly updates the balances.

testSafeTransferFromToEOAByOwnerUpdatesBalances

A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver by the owner correctly updates the balances.

testSafeTransferFromToReceiverByOwnerUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to some EOA correctly updates the balances.

testSafeTransferFromWithDataByApprovedAddressToEOAUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to the contract owner does not update his balance.

testSafeTransferFromWithDataByApprovedAddressToOwnerDoesNotUpdatesBalance

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to some other contract implementing the ERC721Receiver correctly updates the balances.

testSafeTransferFromWithDataByApprovedAddressToReceiverUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved EOA address to self correctly updates the balances.

testSafeTransferFromWithDataByApprovedEOAAddressToSelfUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved ERC721Receiver address to self correctly updates the balances.

testSafeTransferFromWithDataByApprovedReceiverAddressToSelfUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) by an EOA to himself does not update his balance.

testSafeTransferFromWithDataByEOAOwnerToHimSelfDoesNotUpdatesBalance

A safeTransferFrom(address,address,uint256,bytes) (with data) by an operator to an EOA correctly updates the balances.

testSafeTransferFromWithDataByOperatorToEOAUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) by an operator to some other token receiver correctly updates the balances.

testSafeTransferFromWithDataByOperatorToReceiverUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) by an operator to self correctly updates the balances.

testSafeTransferFromWithDataByOperatorToSelfUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) by an ERC721Receiver to himself does not update his balance.

testSafeTransferFromWithDataByReceiverOwnerToHimSelfDoesNotUpdatesBalance

A safeTransferFrom(address,address,uint256,bytes) (with data) to an EOA by the owner correctly updates the balances.

testSafeTransferFromWithDataToEOAByOwnerUpdatesBalances

A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver by the owner correctly updates the balances.

testSafeTransferFromWithDataToReceiverByOwnerUpdatesBalances

A transferFrom(address,address,uint256) by the approved address to some EOA correctly updates the balances.

testTransferFromByApprovedAddressToEOAUpdatesBalances

A transferFrom(address,address,uint256) by the approved address to the contract owner does not update his balance.

testTransferFromByApprovedAddressToOwnerDoesNotUpdatesBalance

A transferFrom(address,address,uint256) by the approved address to some other contract implementing the ERC721Receiver correctly updates the balances.

testTransferFromByApprovedAddressToReceiverUpdatesBalances

A transferFrom(address,address,uint256) by the approved EOA address to self correctly updates the balances.

testTransferFromByApprovedEOAAddressToSelfUpdatesBalances

A transferFrom(address,address,uint256) by the approved ERC721Receiver address to self correctly updates the balances.

testTransferFromByApprovedReceiverAddressToSelfUpdatesBalances

A transferFrom(address,address,uint256) by an EOA to himself does not update his balance.

testTransferFromByEOAOwnerToHimSelfDoesNotUpdatesBalance

A transferFrom(address,address,uint256) by the approved address to an EOA correctly updates the balances.

testTransferFromByOperatorToEOAUpdatesBalances

A transferFrom(address,address,uint256) by the approved address to some other token receiver correctly updates the balances.

testTransferFromByOperatorToReceiverUpdatesBalances

A transferFrom(address,address,uint256) by the approved address to self correctly updates the balances.

testTransferFromByOperatorToSelfUpdatesBalances

A transferFrom(address,address,uint256) by an ERC721Receiver to himself does not update his balance.

testTransferFromByReceiverOwnerToHimSelfDoesNotUpdatesBalance

A transferFrom(address,address,uint256) to an EOA by the owner correctly updates the balances.

testTransferFromToEOAByOwnerUpdatesBalances

A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver by the owner correctly updates the balances.

testTransferFromToReceiverByOwnerUpdatesBalances

PROPERTY
TEST NAME

An operator is approved for any token owned by the address which granted the operator via setApprovalForAll.

testAnOperatorIsApprovedForAnyTokenOfApprover

Any address can query about whether any address is an operator of the zero address.This test excludes the zero address.

testAnyoneCanQueryWhetherAnyoneIsOperatorOfZeroAddress

Any address can query about whether the zero address is an operator of some other address.This test excludes the zero address.

testAnyoneCanQueryWhetherZeroAddressIsOperatorOfAnyone

Function setApprovalForAll(address,bool) can disable self as token operator for a user with tokens.

testCanDisableSelfWithTokensAsOperator

Function setApprovalForAll(address,bool) can disable self as token operator for a user without tokens.

testCanDisableSelfWithoutTokensAsOperator

Function setApprovalForAll(address,bool) can enable self as token operator for a user with tokens.

testCanEnableSelfWithTokensAsOperator

Function setApprovalForAll(address,bool) can enable self as token operator for a user without tokens.

testCanEnableSelfWithoutTokensAsOperator

Function setApprovedForAll(address,bool) does not throw when disabling a valid address as operator.

testDisablingAnyoneAsApprovedIsPossible

Function setApprovedForAll(address,bool) does not throw when enabling a valid address as operator.

testEnablingAnyoneAsApprovedIsPossible

Function name() is implemented and provides a descriptive name for the NFTs in this contract.

testHasName

Function symbol() is implemented and provides an abbreviated name for the NFTs in this contract.

testHasSymbol

Function tokenURI() is implemented and provides a Uniform Resource Identifier.

testHasTokenURI

Users with tokens are operators for themselves.

testIsApprovedForAllReflexiveForUsersWithTokens

Users without token are operators for themselves. Note: the zero address is not considered.

testIsApprovedForAllReflexiveForUsersWithoutTokens

Users with tokens are not operators for themselves.

testIsNotApprovedForAllReflexiveForUsersWithTokens

Users without token are not operators for themselves. Note: the zero address is not considered.

testIsNotApprovedForAllReflexiveForUsersWithoutTokens

Function tokenURI() provides distrinct Uniform Resource Identifier for assets.

testProvidesDistinctTokenURIs

A safeTransferFrom(address,address,uint256,bytes) by someone throws if the recipient is not a TokenReceiver.

testRevertsWhenSafeTransferFromWithDataToRecipientIsNotReceiverBySomeone

A safeTransferFrom(address,address,uint256) by someone throws if the recipient is not a TokenReceiver.

testRevertsWhenSafeTransferFromWithoutDataToRecipientIsNotReceiverBySomeone

A transferFrom(address,address,uint256) by someone throws if the recipient is not a TokenReceiver.

testRevertsWhenTransferFromToRecipientIsNotReceiverBySomeone

The zero address can query about whether some address is an operator.This test excludes the zero address.

testZeroAddressCanQueryWhetherAnyoneIsOperatorOfAnyone

ERC-1155 test suite

PROPERTY
TEST NAME

The safeTransferFrom(address,address,uint256,uint256,bytes) function is present in the contract.

testSafeTransferFrom5Signature

The safeTransferFrom(address,address,uint256,uint256,bytes) function conforms to the EIP-1155 standard.

testSafeTransferFrom5Abi

The safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) function is present in the contract.

testSafeBatchTransferFromSignature

The safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) function conforms to the EIP-1155 standard.

testSafeBatchTransferFromAbi

The balanceOf(address,uint256) function is present in the contract.

testBalanceOf2Signature

The balanceOf(address,uint256) function conforms to the EIP-1155 standard.

testBalanceOf2Abi

The balanceOfBatch(address[],uint256[]) function is present in the contract.

testBalanceOfBatchSignature

The balanceOfBatch(address[],uint256[]) function conforms to the EIP-1155 standard.

testBalanceOfBatchAbi

The setApprovalForAll(address,bool) function is present in the contract.

testSetApprovalForAllSignature

The setApprovalForAll(address,bool) function conforms to the EIP-1155 standard.

testSetApprovalForAllAbi

The isApprovedForAll(address,address) function is present in the contract.

testIsApprovedForAllSignature

The isApprovedForAll(address,address) function conforms to the EIP-1155 standard.

testIsApprovedForAllAbi

The uri(uint256) function is present in the contract.

testUriSignature

The uri(uint256) function conforms to the EIP-1155 standard.

testUriAbi

The supportsInterface(bytes4) function is present in the contract.

testSupportsInterfaceSignature

The supportsInterface(bytes4) function conforms to the EIP-1155 standard.

testSupportsInterfaceAbi

The TransferSingle(address,address,address,uint256,uint256) function is present in the contract.

testTransferSingleEventSignature

The TransferBatch(address,address,address,uint256[],uint256[]) function is present in the contract.

testTransferBatchEventSignature

The ApprovalForAll(address,address,bool) function is present in the contract.

testApprovalForAllEventSignature

The URI(string,uint256) function is present in the contract.

testURIEventSignature

PROPERTY
TEST NAME

Calling of balanceOfBatch of any array of tokenIds does not revert.

testBalanceOfBatchNotRevert

A successful balanceOfBatch call MUST return the correct balances of the provided tokenIds from the provided tokenOwners.

testBalanceOfBatchReturnsCorrectBalances

Calling of balanceOf of any tokenId does not revert.

testBalanceOfNotRevert

A successful balanceOf call MUST return the correct non-zero balance of the provided tokenId from the provided tokenOwner.

testBalanceOfReturnsCorrectNonZeroBalance

A successful balanceOf call MUST return the correct zero balance of the provided tokenId from the provided tokenOwner.

testBalanceOfReturnsCorrectZeroBalance

Calling of isApprovedForAll by any caller on any tokenOwner of any operator does not revert.

testIsApprovedForAllNotRevert

A successful isApprovedForAll call MUST return the approval status of an operator for a given owner correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testIsApprovedForAllReturnsCorrectApprovalStatus

A successful safeBatchTransferFrom call of an array of zero amounts to a contract tokenReceiver MUST emit TransferBatch event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromAllZeroAmountsToContractEventEmission

A successful safeBatchTransferFrom call of an array of zero amounts to an EOA tokenReceiver MUST emit TransferBatch event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromAllZeroAmountsToEoaEventEmission

A safeBatchTransferFrom call MUST be completed if tokenReceiver is a smart contract and it implements onERC1155BatchReceived with the correct return value. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromCompletesWhenCorrectContractReceiverReturn

A safeBatchTransferFrom call MUST revert if any of the balance(s) of the holder(s) for token(s) in tokenIds is lower than the respective amount(s) in tokenAmounts sent to the tokenReceiver (given that the caller has been approved to manage the tokens from the tokenOwner). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromInsufficientBalancesReverts

A successful safeBatchTransferFrom call of any positive amounts to a contract tokenReceiver MUST emit TransferBatch event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromPositiveAmountsToContractEventEmission

A successful safeBatchTransferFrom call of any positive amounts to an EOA tokenReceiver MUST emit TransferBatch event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromPositiveAmountsToEoaEventEmission

A safeBatchTransferFrom call MUST revert if tokenReceiver is a smart contract and it implements onERC1155BatchReceived but throws an error. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromRevertsWhenContractReceiverThrowsError

A safeBatchTransferFrom call MUST revert if tokenReceiver is a smart contract and it implements onERC1155BatchReceived with the incorrect return value. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromRevertsWhenIncorrectContractReceiverReturn

A safeBatchTransferFrom call MUST revert if the caller has not been approved to manage the tokens from the tokenOwner (given that the tokenOwner has sufficient tokenBalances for the respective tokenIds). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromRevertsWhenNoApproval

A successful safeBatchTransferFrom call of an array with some positive and some zero amounts to a contract tokenReceiver MUST emit TransferBatch event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromSomeZeroAmountToContractEventEmission

A successful safeBatchTransferFrom call of an array with some positive and some zero amounts to an EOA tokenReceiver MUST emit TransferBatch event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromSomeZeroAmountToEoaEventEmission

A safeBatchTransferFrom call is SUCCESSFUL if the caller has been approved to manage the tokens from the tokenOwner (given that the tokenOwner has sufficient tokenBalances for respective tokenIds). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromSucceedsWhenApproval

A safeBatchTransferFrom call MUST revert if the tokenReceiver is the zero address (given that the caller has been approved to manage the tokens from the tokenOwner). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromToZeroAddressReverts

A safeBatchTransferFrom call MUST revert if the length of tokenIds is not the same as the length of the tokenBalances (given that the caller has been approved to manage the tokens from the tokenOwner). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromUnequalArrayLengthsReverts

A safeTransferFrom call MUST be completed if tokenReceiver is a smart contract and it implements onERC1155Received with the correct return value. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromCompletesWhenCorrectContractReceiverReturn

A successful safeTransferFrom call of any positive amount to a contract tokenReceiver MUST emit TransferSingle event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromPositiveAmountToContractEventEmission

A successful safeTransferFrom call of any positive amount to an EOA tokenReceiver MUST emit TransferSingle event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromPositiveAmountToEoaEventEmission

A safeTransferFrom call MUST revert if tokenReceiver is a smart contract and it implements onERC1155Received but throws an error. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromRevertsWhenContractReceiverThrowsError

A safeTransferFrom call MUST revert if tokenReceiver is a smart contract and it implements onERC1155Received with the incorrect return value. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromRevertsWhenIncorrectContractReceiverReturn

A safeTransferFrom call MUST revert if the tokenOwner has insufficient tokenBalance of tokenId to be transferred (given that the caller has been approved to manage the tokens from the tokenOwner). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromRevertsWhenInsufficientBalance

A safeTransferFrom call MUST revert if the caller has not been approved to manage the tokens from the tokenOwner (given that the tokenOwner has sufficient tokenBalance of tokenId). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromRevertsWhenNoApproval

A safeTransferFrom call is SUCCESSFUL if the caller has been approved to manage the tokens from the tokenOwner (given that the tokenOwner has sufficient tokenBalance of tokenId). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromSucceedsWhenApproval

A safeTransferFrom call MUST revert if the tokenReceiver is the zero address (given that the caller has been approved to manage the tokens from the tokenOwner). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromToZeroAddressReverts

A successful safeTransferFrom call to a contract tokenReceiver MUST emit TransferSingle event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromZeroAmountToContractEventEmission

A successful safeTransferFrom call of zero amount to an EOA tokenReceiver MUST emit TransferSingle event correctly. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromZeroAmountToEoaEventEmission

An owner SHOULD be able to call safeBatchTransferFrom on his/her own tokens as an operator without the approval of him/herself. NOTE: If testSetApprovalForAllNotRevert and/or testIsApprovedForAll fails, then the result of this test is inconclusive.

testSelfSafeBatchTransferFromWithoutApproval

An owner SHOULD be able to call safeTransferFrom on his/her own tokens as an operator without the approval of him/herself. NOTE: If testSetApprovalForAllNotRevert and/or testIsApprovedForAll fails, then the result of this test is inconclusive.

testSelfSafeTransferFromWithoutApproval

A successful setApprovalForAll call MUST emit ApprovalForAll event correctly.

testSetApprovalForAllEventEmission

Calling of setApprovalForAll of any boolean value does not revert.

testSetApprovalForAllNotRevert

A supportsInterface call MUST be SUCCESSFUL and MUST return the constant value true if 0xd9b67a26 is passed through the interfaceID argument.

testSupportsInterfaceReturnsTrueWhenRequired

PROPERTY
TEST NAME

A balanceOfBatch call reverts if the length of accounts is not the same as the length of the tokenIds.

testBalanceOfBatchUnequalArrayLengthsReverts

A successful safeBatchTransferFrom call increases the tokenBalances of tokenIds for a contract tokenReceiver as expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromIncreaseContractReceiverBalancesAsExpected

A successful safeBatchTransferFrom call increases the tokenBalances of tokenIds for an EOA tokenReceiver as expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromIncreaseEoaReceiverBalancesAsExpected

A safeBatchTransferFrom call MUST revert if the from address, i.e., tokenOwner, is the zero address (given that the caller has been approved to manage the tokens from the tokenOwner). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromRevertsIfFromIsZeroAddress

A successful safeBatchTransferFrom call to a contract tokenReceiver decreases the tokenBalances of tokenIds for tokenOwner as expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromToContractDecreaseOwnerBalancesAsExpected

A successful safeBatchTransferFrom call to an EOA tokenReceiver decreases the tokenBalances of tokenIds for tokenOwner as expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeBatchTransferFromToEoaDecreaseOwnerBalancesAsExpected

A successful safeTransferFrom call increases the tokenBalance of tokenId for a contract tokenReceiver as expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromIncreaseContractReceiverBalanceAsExpected

A successful safeTransferFrom call increases the tokenBalance of tokenId for an EOA tokenReceiver as expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromIncreaseEoaReceiverBalanceAsExpected

A safeTransferFrom call MUST revert if the from address, i.e., tokenOwner, is the zero address (given that the caller has been approved to manage the tokens from the tokenOwner). NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromRevertsIfFromIsZeroAddress

A successful safeTransferFrom call to a contract tokenReceiver decreases the tokenBalance of tokenId for tokenOwner as expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromToContractDecreaseOwnerBalanceAsExpected

A successful safeTransferFrom call to an EOA tokenReceiver decreases the tokenBalance of tokenId for tokenOwner as expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromToEoaDecreaseOwnerBalanceAsExpected

The tokenBalances of tokenIds DO NOT change after a successful safeBatchTransferFrom call by tokenOwner from her account back to herself. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSelfSafeBatchTransferFromSelfToSelfDoNotChangeOwnerBalances

The tokenBalance of any tokenId DOES NOT change after a successful safeTransferFrom call by tokenOwner from her account back to herself. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSelfSafeTransferFromSelfToSelfDoesNotChangeOwnerBalance

Calling of setApprovalForAll with operator set to the zero address MUST revert.

testSetApprovalForAllRevertsIfOperatorIsZeroAddress

PROPERTY
TEST NAME

A successful safeTransferFrom call increases the tokenBalance of tokenId for a contract tokenReceiver greater than what was expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromIncreaseContractReceiverBalanceGtExpected

A successful safeTransferFrom call increases the tokenBalance of tokenId for a contract tokenReceiver less than what was expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromIncreaseContractReceiverBalanceLtExpected

A successful safeTransferFrom call increases the tokenBalance of tokenId for an EOA tokenReceiver greater than what was expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromIncreaseEoaReceiverBalanceGtExpected

A successful safeTransferFrom call increases the tokenBalance of tokenId for an EOA tokenReceiver less than what was expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromIncreaseEoaReceiverBalanceLtExpected

A successful safeTransferFrom call to a contract tokenReceiver decreases the tokenBalance of tokenId for tokenOwner greater than what was expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromToContractDecreaseOwnerBalanceGtExpected

A successful safeTransferFrom call to a contract tokenReceiver decreases the tokenBalance of tokenId for tokenOwner less than what was expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromToContractDecreaseOwnerBalanceLtExpected

A successful safeTransferFrom call to an EOA tokenReceiver decreases the tokenBalance of tokenId for tokenOwner greater than what was expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromToEoaDecreaseOwnerBalanceGtExpected

A successful safeTransferFrom call to an EOA tokenReceiver decreases the tokenBalance of tokenId for tokenOwner less than what was expected. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSafeTransferFromToEoaDecreaseOwnerBalanceLtExpected

The tokenBalance of any tokenId decreases after a successful safeTransferFrom call by tokenOwner from her account back to herself. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSelfSafeTransferFromSelfToSelfDecreasesOwnerBalance

The tokenBalance of any tokenId increases after a successful safeTransferFrom call by tokenOwner from her account back to herself. NOTE: If testSetApprovalForAllNotRevert fails, then the result of this test is inconclusive.

testSelfSafeTransferFromSelfToSelfIncreasesOwnerBalance

ERC-4626 test suite

PROPERTY
TEST NAME

The asset() function conforms to the EIP-4626 standard.

testAssetAbi

The asset() function is present in the contract.

testAssetSignature

The convertToAssets(uint256) function conforms to the EIP-4626 standard.

testConvertToAssetsAbi

The convertToAssets(uint256) function is present in the contract.

testConvertToAssetsSignature

The convertToShares(uint256) function conforms to the EIP-4626 standard.

testConvertToSharesAbi

The convertToShares(uint256) function is present in the contract.

testConvertToSharesSignature

The deposit(uint256,address) function conforms to the EIP-4626 standard.

testDepositAbi

The Deposit(address,address,uint256,uint256) event is present in the contract.

testDepositEventSignature

The deposit(uint256,address) function is present in the contract.

testDepositSignature

The maxDeposit(address) function conforms to the EIP-4626 standard.

testMaxDepositAbi

The maxDeposit(address) function is present in the contract.

testMaxDepositSignature

The maxMint(address) function conforms to the EIP-4626 standard.

testMaxMintAbi

The maxMint(address) function is present in the contract.

testMaxMintSignature

The maxRedeem(address) function conforms to the EIP-4626 standard.

testMaxRedeemAbi

The maxRedeem(address) function is present in the contract.

testMaxRedeemSignature

The maxWithdraw(address) function conforms to the EIP-4626 standard.

testMaxWithdrawAbi

The maxWithdraw(address) function is present in the contract.

testMaxWithdrawSignature

The mint(uint256,address) function conforms to the EIP-4626 standard.

testMintAbi

The mint(uint256,address) function is present in the contract.

testMintSignature

The previewDeposit(uint256) function conforms to the EIP-4626 standard.

testPreviewDepositAbi

The previewDeposit(uint256) function is present in the contract.

testPreviewDepositSignature

The previewMint(uint256) function conforms to the EIP-4626 standard.

testPreviewMintAbi

The previewMint(uint256) function is present in the contract.

testPreviewMintSignature

The previewRedeem(uint256) function conforms to the EIP-4626 standard.

testPreviewRedeemAbi

The previewRedeem(uint256) function is present in the contract.

testPreviewRedeemSignature

The previewWithdraw(uint256) function conforms to the EIP-4626 standard.

testPreviewWithdrawAbi

The previewWithdraw(uint256) function is present in the contract.

testPreviewWithdrawSignature

The redeem(uint256,address,address) function conforms to the EIP-4626 standard.

testRedeemAbi

The redeem(uint256,address,address) function signature is present in the contract.

testRedeemSignature

The totalAssets() function conforms to the EIP-4626 standard.

testTotalAssetsAbi

The totalAssets() function is present in the contract.

testTotalAssetsSignature

The withdraw(uint256,address,address) function conforms to the EIP-4626 standard.

testWithdrawAbi

The Withdraw(address,address,address,uint256,uint256) event is present in the contract.

testWithdrawEventSignature

The withdraw(uint256,address,address) function signature is present in the contract.

testWithdrawSignature

PROPERTY
TEST NAME

Calling asset function MUST NOT revert.

testAssetDoesNotRevert

Calling convertToAssets MUST NOT revert when there is no integer overflow caused by an unreasonably large input.

testConvertToAssetsDoesNotRevertWhenNoIntOverflow

Calling convertToAssets MUST NOT show any variations depending on the caller.

testConvertToAssetsNoVariationOnCaller

Calling convertToShares MUST NOT revert when there is no integer overflow caused by an unreasonably large input.

testConvertToSharesDoesNotRevertWhenNoIntOverflow

Calling convertToShares MUST NOT show any variations depending on the caller.

testConvertToSharesNoVariationOnCaller

ERC4626 MUST implement EIP-20’s optional metadata extensions (in this case is decimals).

testDecimalsCallable

Calling deposit emits Deposit event.

testDepositEmitDepositEvent

The deposit call fails if the caller did not approve the vault enough assets' allowance before he/she can make a deposit, where the vault will do a transferFrom the caller to itself some assets in exchange for shares to be minted for the caller.

testDepositFailsIfInsufficientAssetsAllowanceToVault

deposit supports EIP-20 approve / transferFrom on asset as a deposit flow, i.e., the caller must first approve the vault enough assets' allowance before he/she can make a deposit, where the vault will do a transferFrom the caller to itself some assets in exchange for shares to be minted for the caller.

testDepositSupportsEIP20ApproveTransferFromAssets

Calling maxDeposit MUST NOT revert.

testMaxDepositDoesNotRevert

maxDeposit MUST NOT return a value higher than the actual maximum that would be accepted, i.e., a deposit call can be called on any amount that is lesser than or equal to maxDeposit(receiver) OR maxDeposit(account) == type(uint256).max.

testMaxDepositNotHigherThanActualMax

maxDeposit assumes that the user has infinite assets, i.e. MUST NOT rely on balanceOf of asset.

testMaxDepositNotRelyBalanceOfAssets

Calling maxMint MUST NOT revert.

testMaxMintDoesNotRevert

maxMint MUST NOT return a value higher than the actual maximum that would be accepted, i.e., a mint call can be called on any amount that is lesser than or equal to maxMint(receiver) OR maxMint(account) == type(uint256).max.

testMaxMintNotHigherThanActualMax

maxMint assumes that the user has infinite assets, i.e. MUST NOT rely on balanceOf of asset.

testMaxMintNotRelyBalanceOfAssets

Calling maxRedeem MUST NOT revert.

testMaxRedeemDoesNotRevert

maxRedeem MUST NOT return a value higher than the actual maximum that would be accepted, i.e., a redeem call can be called on any amount that is lesser than or equal to maxRedeem(owner).

testMaxRedeemNotHigherThanActualMax

Calling maxWithdraw MUST NOT revert.

testMaxWithdrawDoesNotRevert

maxWithdraw MUST NOT return a value higher than the actual maximum that would be accepted, i.e., a withdraw call can be called on any amount that is lesser than or equal to maxWithdraw(owner).

testMaxWithdrawNotHigherThanActualMax

Calling mint emits the Deposit event.

testMintEmitDepositEvent

The mint call fails if the caller did not approve the vault enough assets' allowance before he/she can make a mint call, where the vault will do a transferFrom the caller to itself some assets in exchange for shares to be minted for the caller.

testMintFailsIfInsufficientAssetsAllowanceToVault

mint supports EIP-20 approve / transferFrom on asset as a mint flow, i.e., the caller must first approve the vault enough assets' allowance before he/she can make a mint call, where the vault will do a transferFrom the caller to itself some assets in exchange for shares to be minted for the caller.

testMintSupportsEIP20ApproveTransferFromAssets

ERC4626 MUST implement EIP-20’s optional metadata extensions (in this case is name).

testNameCallable

Calling previewDeposit returns as close to and no more than the exact amount of Vault shares (up to delta-approximation) that would be minted in a deposit call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called in the same transaction.

testPreviewDepositSameOrLessThanDeposit

previewMint returns as close to and no fewer than the exact amount of assets (up to delta-approximation) that would be deposited in a mint call in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the same transaction.

testPreviewMintSameOrMoreThanMint

Calling previewRedeem returns as close to and no more than the exact amount of assets (up to delta-approximation) that would be withdrawn in a redeem call in the same transaction.

testPreviewRedeemSameOrLessThanRedeem

Calling previewWithdraw returns as close to and no fewer than the exact amount of Vault shares (up to delta-approximation) that would be burned in a withdraw call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if called in the same transaction

testPreviewWithdrawSameOrMoreThanWithdraw

Calling redeem emits the Withdraw event.

testRedeemEmitWithdrawEvent

A redeem call of some amount of shares SHOULD be successful if there is sufficient shares' allowance from the owner to the msg.sender, i.e., the redeem function SHOULD check msg.sender can spend owner funds using allowance.

testRedeemSenderCanSpendBelowSharesAllowance

A redeem call of some amount of shares SHOULD NOT be successful if there is insufficient shares' allowance from the owner to the msg.sender, i.e., the redeem function SHOULD check msg.sender can spend owner funds using allowance.

testRedeemSenderCannotSpendAboveSharesAllowance

redeem supports a redeem flow where the shares are burned from owner directly (up to delta-approximation) and that the msg.sender has EIP-20 approval over the shares of owner.

testRedeemSupportsBurnSharesFromOwnerWhereOwnerApprovesMsgSender

redeem supports a redeem flow where the shares are burned from owner (up to delta-approximation), who is the msg.sender as well, directly.

testRedeemSupportsBurnSharesFromOwnerWhereOwnerIsMsgSender

ERC4626 MUST implement EIP-20’s optional metadata extensions (in this case is symbol).

testSymbolCallable

Calling totalAssets function MUST NOT revert.

testTotalAssetsDoesNotRevert

The vault.decimals() SHOULD be greater than or equal to asset.decimals().

testVaultDecimalsGeAssetDecimals

Calling withdraw emits the Withdraw event.

testWithdrawEmitWithdrawEvent

A withdraw call of some amount of assets SHOULD be successful if there is sufficient shares' allowance from the owner to the msg.sender, i.e., the withdraw function SHOULD check msg.sender can spend owner funds, assets needs to be converted to shares and shares should be checked for allowance.

testWithdrawSenderCanSpendBelowSharesAllowance

A withdraw call of some amount of assets SHOULD NOT be successful if there is insufficient shares' allowance from the owner to the msg.sender, i.e., the withdraw function SHOULD check msg.sender can spend owner funds, assets needs to be converted to shares and shares should be checked for allowance.

testWithdrawSenderCannotSpendAboveSharesAllowance

withdraw supports a withdraw flow where the shares are burned from owner directly (up to delta-approximation) and that the msg.sender has EIP-20 approval over the shares of owner.

testWithdrawSupportsBurnSharesFromOwnerWhereOwnerApprovesMsgSender

withdraw supports a withdraw flow where the shares are burned from the owner (up to delta-approximation), who is the msg.sender as well, directly.

testWithdrawSupportsBurnSharesFromOwnerWhereOwnerIsMsgSender

PROPERTY
TEST NAME

convertToAssets(convertToShares(assets)) <= assets (up to delta-approximation)

testConvertToAssetsSharesDesirable

Calling convertToAssets of zero amount returns zero, i.e., convertToAssets(0) == 0.

testConvertToAssetsZeroAmountReturnsZero

convertToShares(convertToAssets(shares)) <= shares (up to delta-approximation)

testConvertToSharesAssetsDesirable

Calling convertToShares of zero amount returns zero, i.e., convertToShares(0) == 0.

testConvertToSharesZeroAmountReturnsZero

It is possible to deal the intended amount of assets to dummy users for interacting with the contract.

testDealIntendedAssetsToDummyUsers

Is is possible to deal the intended amount of shares to dummy users for interacting with the contract.

testDealIntendedSharesToDummyUsers

The assets' allowance of caller to vault decreases by the amount of assets deposited (from some initial allowance is greater than or equal to assets) after a successful deposit(assets, receiver) call (up to delta-approximation).

testDepositDecreaseAllowanceCallerVaultAsExpected

The assets' balance of the caller decreases by the amount of assets deposited via a successful deposit(assets, receiver) call (up to delta-approximation).

testDepositDecreaseCallerAssetsAsExpected

The shares' balance of receiver increases by the amount of shares output by a successful deposit(assets, receiver) call (up to delta-approximation).

testDepositIncreaseReceiverSharesAsExpected

The total assets increases by the amount of assets deposited via a successful deposit(assets, receiver) call (up to delta-approximation).

testDepositIncreaseTotalAssetsAsExpected

The total supply of shares increases by the amount of shares output by a successful deposit(assets, receiver) call (up to delta-approximation).

testDepositIncreaseTotalSharesAsExpected

It is not possible to make a free profit through depositing followed by redeeming, i.e., redeem(deposit(assets, caller), caller, caller) <= assets (up to delta-approximation). In layman's terms, it means assets redeemed is less than or equal to initial assets deposited.

testDepositRedeemDesirable

It is not possible to make a free profit through depositing followed by withdrawing, i.e., deposit(assets, caller) <= withdraw(assets, caller, caller) (up to delta-approximation) where deposit is called before withdraw. In layman's terms, it means initial shares minted from depositing is less than or equal to shares burned from withdrawing for same amount of assets.

testDepositWithdrawDesirable

Calling deposit of zero amount to self returns zero, i.e., deposit(0, msg.sender) == 0.

testDepositZeroAmountReturnsZero

The assets' allowance of caller to vault decreases by the amount of assets output by a successful mint(shares, receiver) call (up to delta-approximation).

testMintDecreaseAllowanceCallerVaultAsExpected

The assets' balance of the caller decreases by the amount of assets output by a successful mint(shares, receiver) call (up to delta-approximation).

testMintDecreaseCallerAssetsAsExpected

The shares' balance of receiver increases by the amount of shares minted by a successful mint(shares, receiver) call (up to delta-approximation).

testMintIncreaseReceiverSharesAsExpected

The total assets increases by the amount of assets output by a successful mint(shares, output) call (up to delta-approximation).

testMintIncreaseTotalAssetsAsExpected

The total supply of shares increases by the amount of shares minted by a successful mint(shares, receiver) call (up to delta-approximation).

testMintIncreaseTotalSharesAsExpected

Calling mint of positive amount to self returns a value greater than zero, i.e., mint(shares, msg.sender) > 0 where shares > 0.

testMintPositiveAmountReturnsGtZero

It is not possible to make a free profit through minting followed by redeeming, i.e., mint(shares, caller) >= redeem(shares, caller, caller) (up to delta-approximation) where mint is called before redeem. In layman's terms, it means initial assets lost by caller from minting is greater than or equal to assets gained by caller from redeeming for same amount of shares.

testMintRedeemDesirable

It is not possible to make a free profit through minting followed by withdrawing, i.e., withdraw(mint(shares, caller), caller, caller) >= shares (up to delta-approximation). In layman's terms, it means shares burned from withdrawing is greater than or equal to initial shares minted.

testMintWithdrawDesirable

The return value of a previewDeposit call is independent of the caller's address and assets' balance.

testPreviewDepositIndependentOfCaller

Calling previewDeposit of zero amount returns zero, i.e., previewDeposit(0) == 0.

testPreviewDepositZeroAmountReturnsZero

The return value of a previewMint call is independent of the caller's address and assets' balance.

testPreviewMintIndependentOfCaller

Calling previewMint of positive amount returns a value greater than zero, i.e., previewMint(shares) > 0 where shares > 0.

testPreviewMintPositiveAmountReturnsGtZero

The return value of a previewRedeem call is independent of the caller's address and shares' balance.

testPreviewRedeemIndependentOfCaller

Calling previewRedeem of zero amount returns zero, i.e., previewRedeem(0) == 0.

testPreviewRedeemZeroAmountReturnsZero

The return value of a previewWithdraw call is independent of the caller's address and shares' balance.

testPreviewWithdrawIndependentOfCaller

Calling previewWithdraw of positive amount returns a value greater than zero, i.e., previewWithdraw(assets) > 0 where assets > 0.

testPreviewWithdrawPositiveAmountReturnsGtZero

The shares' allowance of owner to caller decreases by the amount of shares redeemed (from some initial allowance is greater than or equal to shares) after a successful redeem(shares, receiver, owner) call if caller != owner (up to delta-approximation).

testRedeemDecreaseAllowanceOwnerCallerAsExpected

The shares' balance of the owner decreases by the amount of shares redeemed after a successful redeem(shares, receiver, owner) call (up to delta-approximation).

testRedeemDecreaseOwnerSharesAsExpected

The total supply of shares decreases by the amount of shares redeemed after a successful redeem(shares, receiver, owner) call (up to delta-approximation).

testRedeemDecreaseTotalSharesAsExpected

It is not possible to make a free profit through redeeming followed by depositing, i.e., deposit(redeem(shares, caller, caller), caller) <= shares (up to delta-approximation). In layman's terms, it means initial shares redeemed is less than or equal to shares minted from depositing.

testRedeemDepositDesirable

The assets' balance of the receiver increases by the amount of assets output by a successful redeem(shares, receiver, owner) call (up to delta-approximation).

testRedeemIncreaseReceiverAssetsAsExpected

It is not possible to make a free profit through redeeming followed by minting, i.e., redeem(shares, caller, caller) <= mint(shares, caller) (up to delta-approximation) where redeem is called before mint. In layman's terms, it means initial assets gained by caller from redeem is less than or equal to assets lost by caller from minting for same amount of shares.

testRedeemMintDesirable

Calling redeem of zero amount from self to self returns zero, i.e., redeem(0, msg.sender, msg.sender) == 0.

testRedeemZeroAmountReturnsZero

The shares' allowance of owner to caller decreases by the amount of shares output by a successful withdraw(assets, receiver, owner) call if caller != owner (up to delta-approximation).

testWithdrawDecreaseAllowanceOwnerCallerAsExpected

The shares' balance of owner decreases by the amount of shares output by a successful withdraw(assets, receiver, owner) call (up to delta-approximation).

testWithdrawDecreaseOwnerSharesAsExpected

The total supply of shares decreases by the amount of shares output by a successful withdraw(assets, receiver, owner) call (up to delta-approximation).

testWithdrawDecreaseTotalSharesAsExpected

It is not possible to make a free profit through withdrawing followed by depositing, i.e., withdraw(assets, caller, caller) >= deposit(assets, caller) (up to delta-approximation) where withdraw is called before deposit. In layman's terms, it means initial shares burned from withdrawing is greater than or equal to shares minted from depositing for same amount of assets.

testWithdrawDepositDesirable

The assets' balance of the receiver increases by the amount of assets withdrawn after a successful withdraw(assets, receiver, owner) call (up to delta-approximation).

testWithdrawIncreaseReceiverAssetsAsExpected

It is not possible to make a free profit through withdrawing followed by minting, i.e., mint(withdraw(assets, caller, caller), caller) >= assets (up to delta-approximation). In layman's terms, it means shares minted is greater than or equal to initial shares burned from withdrawing.

testWithdrawMintDesirable

Calling withdraw of positive amount from self to self returns a value greater than zero, i.e., withdraw(assets, msg.sender, msg.sender) > 0 where assets > 0.

testWithdrawPositiveAmountReturnsGtZero

PROPERTY
TEST NAME

The contract follows the integer overflow limit used by Solmate ERC4626 implementation for convertToAssets, i.e., calling convertToAssets(shares) reverts due to integer overflow when shares > type(uint256).max / vault.totalAssets().

testConvertToAssetsIntOverflowLimitFollowsSolmate

Calling convertToAssets of zero amount is possible.

testConvertToAssetsZeroAmountIsPossible

The contract follows the integer overflow limit used by Solmate ERC4626 implementation for convertToShares, i.e., calling convertToShares(assets) reverts due to integer overflow when assets > type(uint256).max / vault.totalSupply().

testConvertToSharesIntOverflowLimitFollowsSolmate

Calling convertToShares of zero amount is possible.

testConvertToSharesZeroAmountIsPossible

Calling deposit reverts when the amount of assets to deposit is greater than maxDeposit(tokenReceiver) OR maxDeposit(account) == type(uint256).max.

testDepositRevertsWhenAssetsGtMaxDeposit

Calling deposit of zero amount is possible.

testDepositZeroAmountIsPossible

Calling `maxDeposit MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.

testMaxDepositReturnMaxUint256IfNoLimit

Calling maxMint returns 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.

testMaxMintReturnMaxUint256IfNoLimit

maxRedeem(account) == vault.balanceOf(account) (referenced from Solmate and OZ implementation)

testMaxRedeemEqBalanceOfShares

maxWithdraw(account) == convertToAssets(vault.balanceOf(account)) (referenced from Solmate and OZ implementation)

testMaxWithdrawEqConvertToAssetsOfBalanceOfShares

Calling mint reverts when the amount of shares to mint is greater than maxMint(tokenReceiver) OR maxMint(account) == type(uint256).max.

testMintRevertsWhenSharesGtMaxMint

Calling mint of zero amount is possible.

testMintZeroAmountIsPossible

There is no discrepancy between convertToAssets and previewMint.

testNoDiscrepancyConvertToAssetsAndPreviewMint

There is no discrepancy between convertToAssets and previewRedeem.

testNoDiscrepancyConvertToAssetsAndPreviewRedeem

There is no discrepancy between convertToShares and previewDeposit.

testNoDiscrepancyConvertToSharesAndPreviewDeposit

There is no discrepancy between convertToShares and previewWithdraw.

testNoDiscrepancyConvertToSharesAndPreviewWithdraw

Calling previewDeposit of zero amount is possible.

testPreviewDepositZeroAmountIsPossible

Calling previewMint of zero amount is possible.

testPreviewMintZeroAmountIsPossible

Calling previewRedeem of zero amount is possible.

testPreviewRedeemZeroAmountIsPossible

Calling previewWithdraw of zero amount is possible.

testPreviewWithdrawZeroAmountIsPossible

Calling redeem reverts when the amount of shares to redeem is greater than maxRedeem(tokenOwner).

testRedeemRevertsWhenSharesGtMaxRedeem

Calling redeem of zero amount is possible.

testRedeemZeroAmountIsPossible

The vault token is transferrable via transfer, i.e., it does not revert on calls to transfer.

testSharesIsTransferAble

The vault token is transferrable via transferFrom, i.e., it does not revert on calls to transferFrom.

testSharesIsTransferFromAble

vault.totalAssets() > vault.totalSupply()

testTotalAssetsGtTotalSupply

vault.totalAssets() > asset.balanceOf(vault)

testTotalAssetsGtVaultAssetsBalance

vault.totalAssets() > 0

testTotalAssetsGtZero

vault.totalAssets() < vault.totalSupply()

testTotalAssetsLtTotalSupply

vault.totalAssets() < asset.balanceOf(vault)

testTotalAssetsLtVaultAssetsBalance

vault.totalSupply() > 0

testTotalSupplyGtZero

Calling withdraw reverts when the amount of assets to withdraw is greater than maxWithdraw(tokenOwner).

testWithdrawRevertsWhenAssetsGtMaxWithdraw

Calling withdraw of zero amount is possible.

testWithdrawZeroAmountIsPossible

For ERC-4626 test suite, there are several tests with the phrase "up todelta-approximation" in their test descriptions. These are the tests where calling of functions such as deposit,withdraw, etc, are being carried out and conversation of shares to assets, and vice-versa, will take place. As math operations in Solidity is done entirely using fixed-point (i.e., no decimal value), rounding errors may occur if the contract does not follow the required rounding rules stated in the standard. However, in the event where the contract does not follow the required rounding rules, there is a global uint256 variable, delta, for the test suite where the user can set to provide some leeway for such errors. This delta value represents the maximum approximation error size (an absolute value given in the smallest unit such as Wei) whenever equality assertion check is carried out. For example, x - y <= delta is being checked whenever there is a check for x == y. It is important to note that delta should only be set to a reasonable small value so that the adversarial profit of exploiting such rounding errors stays relatively small compared to the gas cost. The default value of delta is set to 0 as all tests are supposed to pass at this value if the contract follows the required rounding rules.

contact us
EIP-4626