Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions PROPERTIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ This file lists all the currently implemented Echidna property tests for ERC20,
| ERC20-BASE-015 | [test_ERC20_setAllowance](https://github.com/crytic/properties/blob/main/contracts/ERC20/internal/properties/ERC20BasicProperties.sol#L160) | Allowances should be set correctly when `approve` is called. |
| ERC20-BASE-016 | [test_ERC20_setAllowanceTwice](https://github.com/crytic/properties/blob/main/contracts/ERC20/internal/properties/ERC20BasicProperties.sol#L167) | Allowances should be updated correctly when `approve` is called twice. |
| ERC20-BASE-017 | [test_ERC20_spendAllowanceAfterTransfer](https://github.com/crytic/properties/blob/main/contracts/ERC20/internal/properties/ERC20BasicProperties.sol#L178) | After `transferFrom`, allowances should be updated correctly. |
| ERC20-BASE-018 | [test_ERC20_transferFromMoreThanAllowance](https://github.com/crytic/properties/blob/main/contracts/ERC20/internal/properties/ERC20BasicProperties.sol#L294) | `transferFrom`s for more than allowance should not be allowed. |

### Tests for burnable tokens

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,30 @@ abstract contract CryticERC20ExternalBasicProperties is
);
}
}

// Transfers for more than allowance should not be allowed
function test_ERC20external_transferFromMoreThanAllowance(
address target
) public {
uint256 balance_sender = token.balanceOf(msg.sender);
uint256 balance_receiver = token.balanceOf(target);
uint256 allowance = token.allowance(msg.sender, address(this));
require(balance_sender > 0 && allowance < balance_sender);

bool r = token.transferFrom(msg.sender, target, allowance + 1);
assertWithMsg(
r == false,
"Successful transferFrom for more than allowance"
);
assertEq(
token.balanceOf(msg.sender),
balance_sender,
"TransferFrom for more than amount approved source allowance"
);
assertEq(
token.balanceOf(target),
balance_receiver,
"TransferFrom for more than amount approved target allowance"
);
}
}
26 changes: 26 additions & 0 deletions contracts/ERC20/internal/properties/ERC20BasicProperties.sol
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,30 @@ abstract contract CryticERC20BasicProperties is CryticERC20Base {
);
}
}

// TransferFrom for more than allowance should not be allowed
function test_ERC20_transferFromMoreThanAllowance(
address target
) public {
uint256 balance_sender = balanceOf(msg.sender);
uint256 balance_receiver = balanceOf(target);
uint256 allowance = allowance(msg.sender, address(this));
require(balance_sender > 0 && allowance < balance_sender);

bool r = this.transferFrom(msg.sender, target, allowance + 1);
assertWithMsg(
r == false,
"Successful transferFrom for more than allowance"
);
assertEq(
balanceOf(msg.sender),
balance_sender,
"TransferFrom for more than amount approved source allowance"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure if i understand the 4 error messages, if given out of context (like, when the property fails).
something like "TransferFrom for more than approval affected sender/receiver balance" should be clearer, what do you think?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the error messages, let me know if they sound clearer now.

);
assertEq(
balanceOf(target),
balance_receiver,
"TransferFrom for more than amount approved target allowance"
);
}
}