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 contact us 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver can be initiated by the approved address to self.
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.
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.
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.
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.
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.
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.
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.
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.
Event Transfer emits when ownership of tokens changes with transferFrom(address,address,uint256) by token owner to a contract implementing the ERC721Receiver interface.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver by someone throws if _from (the first address) is not the token owner.
A safeTransferFrom(address,address,uint256) (without data) to a contract implementing the ERC721Receiver interface throws if tokenID (uint256) is not a valid token id.
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.
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.
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.
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.
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.
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.
A safeTransferFrom(address,address,uint256) (without data) by an operator to some contract implementing the ERC721Receiver interface correctly updates the ownership.
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.
A safeTransferFrom(address,address,uint256) (without data) by the token owner to a contract implementing the ERC721Receiver correctly updates the ownership.
A safeTransferFrom(address,address,uint256) contract implementing the ERC721Receiver interface by an operator correctly resets the approved address for that token.
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.
A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to some contract implementing the ERC721Receiver interface correctly updates the ownership.
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.
A safeTransferFrom(address,address,uint256,bytes) (with data) by the token owner to a contract implementing the ERC721Receiver correctly updates the ownership.
A safeTransferFrom(address,address,uint256,bytes) contract implementing the ERC721Receiver interface by an operator correctly resets the approved address for that token.
A transferFrom(address,address,uint256) to a contract implementing the ERC721Receiver interface by the approved address correctly resets the approved address for that token.
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.
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.
A transferFrom(address,address,uint256) contract implementing the ERC721Receiver interface by an operator correctly resets the approved address for that token.
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.
A transferFrom(address,address,uint256) by someone throws if the recipient does not return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) when calling onERC721Received.
A safeTransferFrom(address,address,uint256) (without data) by the approved address to some other contract implementing the ERC721Receiver correctly updates the balances.
A safeTransferFrom(address,address,uint256,bytes) (with data) by the approved address to some other contract implementing the ERC721Receiver correctly updates the balances.
A safeTransferFrom(address,address,uint256,bytes) (with data) to a contract implementing the ERC721Receiver by the owner correctly updates the balances.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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 EIP-4626 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.