Skip to content
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

Gas Optimizations #93

Open
code423n4 opened this issue Apr 2, 2022 · 1 comment
Open

Gas Optimizations #93

code423n4 opened this issue Apr 2, 2022 · 1 comment
Labels
bug Something isn't working G (Gas Optimization)

Comments

@code423n4
Copy link
Contributor

gas

#1 Unnecessary require()
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L183
transferOwnership() function was validating that _admin != address(0). I recommend to remove L183 or call _transferOwnerShip() instead of transferOwnership

#2 != is more effective than >
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L229
Using != 0 is more gas effective > 0

#3 Using SafeERC20 Lib for pal token
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L13
Using SafeERC20.function for pal token is unnecessary. Using just transfer and transferFrom from ERC20.function is gas saving

#4 Unnecessary burnAmountx variable declaration in _unstake function
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L1090
Instead of using ternary operation, using if() statement can save gas, then just store the value amount to burn to amount var:

If(amount > userAvailableBalance){
	amount = userAvailableBalance;
}
_burn(user, amount);
pal.safeTransfer(receiver, amount);
emit Unstake(user, amount);
return amount

#5 Declaration bool with default value
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L103
By not declaring that emergency = false, the value will still == false. So delete the value set at L103

#6 Unnecessary rewardLastUpdate[user] == block.timestamp
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L861
The only way to update rewardLastUpdate[user]is in the same function (_updateUserReward()). Therefore, the condition rewardLastUpdate[user] == block.timestamp is an edge case (its quite hard to have exact the same block.timestamp since it is updated per second), and have no security risk.

#7 Using if() statement instead of ternary operation
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L1206
By using if() statement, MSTORE when the condition == false will prevented and also reducing gas cost

If(action == LockAction.INCREASE_AMOUNT) startTimestamp = currentUserLock.startTimestamp;

#8 Prevent too many SLOAD and using if instead of ternary operation
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L388
By chacing claimableReward[msg.sender] to claimAmount and using if condition to set claimAmount = amount (also prevent MSTORE) can be a lot efficient:

uint claimAmount = claimableRewards[msg.sender];

if(amount < claimAmount)claimAmount = amount;

#9 Gas improvement on calling SafeERC20.function
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L13
In case SafeERC20 is used. By removing L13 and call SafeERC20.function directly in line can save 15 gas per call.
For instance:

SafeERC20.safeTransfer(pal, msg.sender, burnAmount)

#10 Using storage instead of memory to declare struct
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L650
Instead of chasing UserLock in memory, read it directly from storage can save gas (if struct var amount > how many time it was called, better using storage pointer)

UserLock storage pastLock = _getPastLock(user, blockNumber);

#11 Unnecessary votes variable declaration
https://github.com/code-423n4/2022-03-paladin/blob/main/contracts/HolyPaladinToken.sol#L646
votes is merely called once in the getPastVotes function. Avoiding unnecessary MSTORE and pass it directly to L645 can save gas:

Return _getPastVotes(user, blockNumber) + bonusVotes;
@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels Apr 2, 2022
code423n4 added a commit that referenced this issue Apr 2, 2022
@Kogaroshi
Copy link
Collaborator

QA & gas optimizations changes are done in the PR: PaladinFinance/Paladin-Tokenomics#6
(some changes/tips were implemented, others are noted but won't be applied)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working G (Gas Optimization)
Projects
None yet
Development

No branches or pull requests

2 participants