Skip to content

Commit

Permalink
✅ delete validation of checking token address is not zero in `_distri…
Browse files Browse the repository at this point in the history
…bute()` and fix test (#39)

* ✅ delete validation of checking token address is not zero in `_distribute()` and fix test

* ⚡️ improve gas by `++i`

* ⚡️ gas optimizations:
- use calldata
- cache `winner, percentage and winnersLength`
- fix magic number `10_000`
  • Loading branch information
thurendous authored Oct 3, 2023
1 parent d38a9f5 commit c6c030e
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 15 deletions.
27 changes: 14 additions & 13 deletions src/Distributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ contract Distributor {
address private immutable STADIUM_ADDRESS;
uint256 private constant COMMISSION_FEE = 500; // this can be changed in the future
// a constant value of 10,000 (basis points) = 100%
uint256 private constant BASIS_POINTS = 10000;
uint256 private constant BASIS_POINTS = 10_000;

// prize distribution event. data is for logging purpose
event Distributed(address token, address[] winners, uint256[] percentages, bytes data);
Expand Down Expand Up @@ -88,7 +88,7 @@ contract Distributor {
* @param winners The addresses array of winners
* @param percentages The percentages array of winners
*/
function distribute(address token, address[] memory winners, uint256[] memory percentages, bytes memory data)
function distribute(address token, address[] calldata winners, uint256[] calldata percentages, bytes calldata data)
external
{
if (msg.sender != FACTORY_ADDRESS) {
Expand All @@ -112,39 +112,40 @@ contract Distributor {
* @param percentages The percentages of winners
* @param data The data to be logged. It is supposed to be used for showing the realation bbetween winners and proposals.
*/
function _distribute(address token, address[] memory winners, uint256[] memory percentages, bytes memory data)
function _distribute(address token, address[] calldata winners, uint256[] calldata percentages, bytes calldata data)
internal
{
// token address input check
if (token == address(0)) revert Distributor__NoZeroAddress();
if (!_isWhiteListed(token)) {
revert Distributor__InvalidTokenAddress();
}
// winners and percentages input check
if (winners.length == 0 || winners.length != percentages.length) revert Distributor__MismatchedArrays();
uint256 winnersLength = winners.length; // cache length
if (winners.length == 0 || winnersLength != percentages.length) revert Distributor__MismatchedArrays();

// prepare for the loop
IERC20 erc20 = IERC20(token);
// cashe the total amount of token to distribute
uint256 totalAmount = erc20.balanceOf(address(this));
// if there is no token to distribute, then revert
if (totalAmount == 0) revert Distributor__NoTokenToDistribute();

// percentages.length = winners length
uint256 winnersLength = winners.length; // cache length

// percentages.length is equal to winners length
uint256 totalPercentage;
for (uint256 i; i < winnersLength;) {
totalPercentage += percentages[i];
uint256 amount = totalAmount * percentages[i] / BASIS_POINTS;
if (winners[i] == address(0)) revert Distributor__NoZeroAddress();
erc20.safeTransfer(winners[i], amount);
uint256 percentage = percentages[i];
totalPercentage += percentage;
uint256 amount = totalAmount * percentage / BASIS_POINTS;
address winner = winners[i];
if (winner == address(0)) revert Distributor__NoZeroAddress();
erc20.safeTransfer(winner, amount);
unchecked {
++i;
}
}

// check if totalPercentage is correct
if (totalPercentage != (10000 - COMMISSION_FEE)) {
if (totalPercentage != (BASIS_POINTS - COMMISSION_FEE)) {
revert Distributor__MismatchedPercentages();
}

Expand Down
2 changes: 1 addition & 1 deletion src/ProxyFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ contract ProxyFactory is Ownable, EIP712 {
if (_whitelistedTokens[i] == address(0)) revert ProxyFactory__NoZeroAddress();
whitelistedTokens[_whitelistedTokens[i]] = true;
unchecked {
i++;
++i;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/ProxyTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ contract ProxyTest is StdCheats, HelperContract {

// factory wants to call distribute function but with address zero
vm.startPrank(address(proxyFactory));
vm.expectRevert(Distributor.Distributor__NoZeroAddress.selector);
vm.expectRevert(Distributor.Distributor__InvalidTokenAddress.selector);
proxyWithDistributorLogic.distribute(address(0), winners, percentages_, "");
vm.stopPrank();
}
Expand Down

0 comments on commit c6c030e

Please sign in to comment.