forked from balancer/balancer-core
-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: adding btt tests for bToken #167
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,154 +1,94 @@ | ||
// SPDX-License-Identifier: GPL-3 | ||
pragma solidity ^0.8.25; | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity 0.8.25; | ||
|
||
import {IERC20Errors} from '@openzeppelin/contracts/interfaces/draft-IERC6093.sol'; | ||
import {Test} from 'forge-std/Test.sol'; | ||
import {MockBToken} from 'test/smock/MockBToken.sol'; | ||
|
||
contract BToken_Unit_Constructor is Test { | ||
function test_ConstructorParams() public { | ||
MockBToken btoken = new MockBToken(); | ||
assertEq(btoken.name(), 'Balancer Pool Token'); | ||
assertEq(btoken.symbol(), 'BPT'); | ||
assertEq(btoken.decimals(), 18); | ||
} | ||
} | ||
contract BToken is Test { | ||
MockBToken public bToken; | ||
uint256 public initialApproval = 100e18; | ||
uint256 public initialBalance = 100e18; | ||
address public caller = makeAddr('caller'); | ||
address public spender = makeAddr('spender'); | ||
address public target = makeAddr('target'); | ||
|
||
abstract contract BToken_Unit_base is Test { | ||
MockBToken internal bToken; | ||
function setUp() external { | ||
bToken = new MockBToken(); | ||
|
||
modifier assumeNonZeroAddresses(address addr1, address addr2) { | ||
vm.assume(addr1 != address(0)); | ||
vm.assume(addr2 != address(0)); | ||
_; | ||
vm.startPrank(caller); | ||
// sets initial approval (cannot be mocked) | ||
bToken.approve(spender, initialApproval); | ||
} | ||
|
||
modifier assumeNonZeroAddress(address addr) { | ||
vm.assume(addr != address(0)); | ||
_; | ||
function test_ConstructorWhenCalled() external { | ||
MockBToken _bToken = new MockBToken(); | ||
// it sets token name | ||
assertEq(_bToken.name(), 'Balancer Pool Token'); | ||
// it sets token symbol | ||
assertEq(_bToken.symbol(), 'BPT'); | ||
} | ||
|
||
function setUp() public virtual { | ||
bToken = new MockBToken(); | ||
function test_IncreaseApprovalRevertWhen_SenderIsAddressZero() external { | ||
vm.startPrank(address(0)); | ||
// it should revert | ||
vm.expectRevert(abi.encodeWithSelector(IERC20Errors.ERC20InvalidApprover.selector, address(0))); | ||
|
||
bToken.increaseApproval(spender, 100e18); | ||
} | ||
} | ||
|
||
contract BToken_Unit_IncreaseApproval is BToken_Unit_base { | ||
function test_increasesApprovalFromZero( | ||
address sender, | ||
address spender, | ||
uint256 amount | ||
) public assumeNonZeroAddresses(sender, spender) { | ||
vm.prank(sender); | ||
bToken.increaseApproval(spender, amount); | ||
assertEq(bToken.allowance(sender, spender), amount); | ||
function test_IncreaseApprovalRevertWhen_SpenderIsAddressZero() external { | ||
// it should revert | ||
vm.expectRevert(abi.encodeWithSelector(IERC20Errors.ERC20InvalidSpender.selector, address(0))); | ||
bToken.increaseApproval(address(0), 100e18); | ||
} | ||
|
||
function test_increasesApprovalFromNonZero( | ||
address sender, | ||
address spender, | ||
uint128 existingAllowance, | ||
uint128 amount | ||
) public assumeNonZeroAddresses(sender, spender) { | ||
vm.assume(existingAllowance > 0); | ||
vm.startPrank(sender); | ||
bToken.approve(spender, existingAllowance); | ||
bToken.increaseApproval(spender, amount); | ||
vm.stopPrank(); | ||
assertEq(bToken.allowance(sender, spender), uint256(amount) + existingAllowance); | ||
function test_IncreaseApprovalWhenCalled() external { | ||
bToken.increaseApproval(spender, 100e18); | ||
// it increases spender approval | ||
assertEq(bToken.allowance(caller, spender), 200e18); | ||
} | ||
} | ||
|
||
contract BToken_Unit_DecreaseApproval is BToken_Unit_base { | ||
function test_decreaseApprovalToNonZero( | ||
address sender, | ||
address spender, | ||
uint256 existingAllowance, | ||
uint256 amount | ||
) public assumeNonZeroAddresses(sender, spender) { | ||
existingAllowance = bound(existingAllowance, 1, type(uint256).max); | ||
amount = bound(amount, 0, existingAllowance - 1); | ||
vm.startPrank(sender); | ||
bToken.approve(spender, existingAllowance); | ||
bToken.decreaseApproval(spender, amount); | ||
vm.stopPrank(); | ||
assertEq(bToken.allowance(sender, spender), existingAllowance - amount); | ||
function test_DecreaseApprovalRevertWhen_SenderIsAddressZero() external { | ||
vm.startPrank(address(0)); | ||
// it should revert | ||
vm.expectRevert(abi.encodeWithSelector(IERC20Errors.ERC20InvalidApprover.selector, address(0))); | ||
bToken.decreaseApproval(spender, 50e18); | ||
} | ||
|
||
function test_decreaseApprovalToZero( | ||
address sender, | ||
address spender, | ||
uint256 existingAllowance, | ||
uint256 amount | ||
) public assumeNonZeroAddresses(sender, spender) { | ||
amount = bound(amount, existingAllowance, type(uint256).max); | ||
vm.startPrank(sender); | ||
bToken.approve(spender, existingAllowance); | ||
bToken.decreaseApproval(spender, amount); | ||
vm.stopPrank(); | ||
assertEq(bToken.allowance(sender, spender), 0); | ||
function test_DecreaseApprovalRevertWhen_SpenderIsAddressZero() external { | ||
// it should revert | ||
vm.expectRevert(abi.encodeWithSelector(IERC20Errors.ERC20InvalidSpender.selector, address(0))); | ||
bToken.decreaseApproval(address(0), 50e18); | ||
} | ||
} | ||
|
||
contract BToken_Unit__push is BToken_Unit_base { | ||
function test_revertsOnInsufficientSelfBalance( | ||
address to, | ||
uint128 existingBalance, | ||
uint128 offset | ||
) public assumeNonZeroAddress(to) { | ||
vm.assume(offset > 1); | ||
deal(address(bToken), address(bToken), existingBalance); | ||
vm.expectRevert( | ||
abi.encodeWithSelector( | ||
IERC20Errors.ERC20InsufficientBalance.selector, | ||
address(bToken), | ||
existingBalance, | ||
uint256(existingBalance) + offset | ||
) | ||
); | ||
bToken.call__push(to, uint256(existingBalance) + offset); | ||
function test_DecreaseApprovalWhenDecrementIsBiggerThanCurrentApproval() external { | ||
bToken.decreaseApproval(spender, 200e18); | ||
// it decreases spender approval to 0 | ||
assertEq(bToken.allowance(caller, spender), 0); | ||
} | ||
|
||
function test_sendsTokens( | ||
address to, | ||
uint128 existingBalance, | ||
uint256 transferAmount | ||
) public assumeNonZeroAddress(to) { | ||
vm.assume(to != address(bToken)); | ||
transferAmount = bound(transferAmount, 0, existingBalance); | ||
deal(address(bToken), address(bToken), existingBalance); | ||
bToken.call__push(to, transferAmount); | ||
assertEq(bToken.balanceOf(to), transferAmount); | ||
assertEq(bToken.balanceOf(address(bToken)), existingBalance - transferAmount); | ||
function test_DecreaseApprovalWhenCalled() external { | ||
bToken.decreaseApproval(spender, 50e18); | ||
// it decreases spender approval | ||
assertEq(bToken.allowance(caller, spender), 50e18); | ||
} | ||
} | ||
|
||
contract BToken_Unit__pull is BToken_Unit_base { | ||
function test_revertsOnInsufficientFromBalance( | ||
address from, | ||
uint128 existingBalance, | ||
uint128 offset | ||
) public assumeNonZeroAddress(from) { | ||
vm.assume(offset > 1); | ||
deal(address(bToken), from, existingBalance); | ||
vm.expectRevert( | ||
abi.encodeWithSelector( | ||
IERC20Errors.ERC20InsufficientBalance.selector, from, existingBalance, uint256(existingBalance) + offset | ||
) | ||
); | ||
bToken.call__pull(from, uint256(existingBalance) + offset); | ||
function test__pushWhenCalled() external { | ||
deal(address(bToken), address(bToken), initialBalance); | ||
bToken.call__push(target, 50e18); | ||
|
||
// it transfers tokens to recipient | ||
assertEq(bToken.balanceOf(address(bToken)), 50e18); | ||
assertEq(bToken.balanceOf(target), 50e18); | ||
} | ||
|
||
function test_getsTokens( | ||
address from, | ||
uint128 existingBalance, | ||
uint256 transferAmount | ||
) public assumeNonZeroAddress(from) { | ||
vm.assume(from != address(bToken)); | ||
transferAmount = bound(transferAmount, 0, existingBalance); | ||
deal(address(bToken), address(from), existingBalance); | ||
bToken.call__pull(from, transferAmount); | ||
assertEq(bToken.balanceOf(address(bToken)), transferAmount); | ||
assertEq(bToken.balanceOf(from), existingBalance - transferAmount); | ||
function test__pullWhenCalled() external { | ||
deal(address(bToken), address(target), initialBalance); | ||
bToken.call__pull(target, 50e18); | ||
|
||
// it transfers tokens from sender | ||
assertEq(bToken.balanceOf(target), 50e18); | ||
assertEq(bToken.balanceOf(address(bToken)), 50e18); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
BToken::constructor | ||
└── when called | ||
├── it sets token name | ||
└── it sets token symbol | ||
|
||
BToken::increaseApproval | ||
├── when sender is address zero | ||
│ └── it should revert | ||
├── when spender is address zero | ||
│ └── it should revert | ||
└── when called | ||
└── it increases spender approval | ||
0xteddybear marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
BToken::decreaseApproval | ||
├── when sender is address zero | ||
│ └── it should revert | ||
├── when spender is address zero | ||
│ └── it should revert | ||
├── when decrement is bigger than current approval | ||
│ └── it decreases spender approval to 0 | ||
└── when called | ||
└── it decreases spender approval | ||
|
||
BToken::_push | ||
└── when called | ||
└── it transfers tokens to recipient | ||
|
||
BToken::_pull | ||
└── when called | ||
└── it transfers tokens from sender |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how could we get to this? I imagine the assertion was added to OZ to avoid programeer errors when calling the internal method, but is there any context in where an external caller could be
address(0)
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm is not, but is an actual possible branch, it actually happens inside
_approve
so tbh i wouldn't care so much for it