Skip to content

Commit

Permalink
feat: code4rena gas opts (#105)
Browse files Browse the repository at this point in the history
* renamed folder and changed version

* npmignore

* npmignore

* change version

* using include pattern instead.

* Fixed most of the things least auhority suggested.

* made lint happy

* Apply suggestions from code review

* fixed some bugs

* added events

* rename set to transfer for distributor and operator

* changed standardized token to always allow token managers to mint/burn it.

* using immutable storage for remoteAddressValidator address to save gas

* Added some recommended changes

* added milap's suggested changes

* Fixed some names and some minor gas optimizations

* prettier and lint

* stash

* import .env in hardhat.config

* trying to fix .env.example

* Added some getters in IRemoteAddressValidator and removed useless check for distributor in the InterchainTokenService.

* removed ternary operators

* made lint happy

* made lint happy

* Added a new token manager to handle fee on transfer and added some tests for it as well

* fixed the liquidity pool check.

* fix a duplication bug

* lint

* added some more tests

* Added more tests

* Added proper re-entrancy protection for fee on transfer token managers.

* change to tx.origin for refunds

* Added support for more kinds of addresses.

* some minor gas opts

* some more gas optimizations.

* Added a getter for chain name to the remote address validator.

* moved the tokenManager getter functionality to a separate contract which saves almost a kilobyte of codesize.

* made lint happy

* Removed tokenManagerGetter and put params into tokenManagers

* Added separate tokenManager interfaces

* addressed ackeeblockchains's 3.0 report

* prettier

* added interchain transfer methods to the service and unified receiving tokens a bit.

* made lint happy

* rename sendToken to interchainTransfer

* changed sendToken everywhere

* changed from uint256.max to a const

* change setting to zero to delete for storage slots.

* rearange storage variables to save a bit of gas.

* Removed unecesairy casts

* made as many event params inexed as possible

* Removed unused imports

---------

Co-authored-by: Milap Sheth <[email protected]>
Co-authored-by: Kiryl Yermakou <[email protected]>
  • Loading branch information
3 people authored Oct 2, 2023
1 parent 403e3bd commit 926e025
Show file tree
Hide file tree
Showing 12 changed files with 21 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

pragma solidity ^0.8.0;

import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol';
import { AxelarExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol';
import { SafeTokenTransferFrom } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/SafeTransfer.sol';
Expand Down
2 changes: 1 addition & 1 deletion contracts/interchain-token/InterchainToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ abstract contract InterchainToken is IInterchainToken, ERC20 {
) external payable {
uint256 _allowance = allowance[sender][msg.sender];

if (_allowance != type(uint256).max) {
if (_allowance != UINT256_MAX) {
_approve(sender, msg.sender, _allowance - amount);
}

Expand Down
12 changes: 5 additions & 7 deletions contracts/interfaces/IInterchainTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

pragma solidity ^0.8.0;

import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
import { IAxelarExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarExecutable.sol';

import { IExpressCallHandler } from './IExpressCallHandler.sol';
import { ITokenManagerDeployer } from './ITokenManagerDeployer.sol';
import { ITokenManagerType } from './ITokenManagerType.sol';
import { IPausable } from './IPausable.sol';
import { IMulticall } from './IMulticall.sol';
Expand All @@ -30,9 +28,9 @@ interface IInterchainTokenService is ITokenManagerType, IExpressCallHandler, IAx
error AlreadyExecuted(bytes32 commandId);
error InvalidExpressSelector();

event TokenSent(bytes32 tokenId, string destinationChain, bytes destinationAddress, uint256 indexed amount);
event TokenSent(bytes32 indexed tokenId, string destinationChain, bytes destinationAddress, uint256 indexed amount);
event TokenSentWithData(
bytes32 tokenId,
bytes32 indexed tokenId,
string destinationChain,
bytes destinationAddress,
uint256 indexed amount,
Expand Down Expand Up @@ -62,19 +60,19 @@ interface IInterchainTokenService is ITokenManagerType, IExpressCallHandler, IAx
uint8 tokenDecimals,
bytes distributor,
bytes mintTo,
uint256 mintAmount,
uint256 indexed mintAmount,
bytes operator,
string destinationChain,
uint256 indexed gasValue
);
event TokenManagerDeployed(bytes32 indexed tokenId, TokenManagerType indexed tokenManagerType, bytes params);
event StandardizedTokenDeployed(
bytes32 indexed tokenId,
address distributor,
address indexed distributor,
string name,
string symbol,
uint8 decimals,
uint256 mintAmount,
uint256 indexed mintAmount,
address mintTo
);
event CustomTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt);
Expand Down
2 changes: 1 addition & 1 deletion contracts/interfaces/IPausable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pragma solidity ^0.8.0;
* if a pause condition is activated.
*/
interface IPausable {
event PausedSet(bool paused);
event PausedSet(bool indexed paused);

error Paused();

Expand Down
4 changes: 2 additions & 2 deletions contracts/remote-address-validator/RemoteAddressValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ contract RemoteAddressValidator is IRemoteAddressValidator, Upgradable {
function removeTrustedAddress(string calldata sourceChain) external onlyOwner {
if (bytes(sourceChain).length == 0) revert ZeroStringLength();

remoteAddressHashes[sourceChain] = bytes32(0);
remoteAddresses[sourceChain] = '';
delete remoteAddressHashes[sourceChain];
delete remoteAddresses[sourceChain];

emit TrustedAddressRemoved(sourceChain);
}
Expand Down
7 changes: 4 additions & 3 deletions contracts/test/FeeOnTransferTokenTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { IERC20BurnableMintable } from '../interfaces/IERC20BurnableMintable.sol
contract FeeOnTransferTokenTest is InterchainToken, Distributable, IERC20BurnableMintable {
ITokenManager public tokenManager_;
bool internal tokenManagerRequiresApproval_ = true;

string public name;
string public symbol;
uint8 public decimals;
Expand All @@ -36,9 +37,9 @@ contract FeeOnTransferTokenTest is InterchainToken, Distributable, IERC20Burnabl
if (!tokenManagerRequiresApproval_) return;
address tokenManagerAddress = address(tokenManager_);
uint256 allowance_ = allowance[sender][tokenManagerAddress];
if (allowance_ != type(uint256).max) {
if (allowance_ > type(uint256).max - amount) {
allowance_ = type(uint256).max - amount;
if (allowance_ != UINT256_MAX) {
if (allowance_ > UINT256_MAX - amount) {
allowance_ = UINT256_MAX - amount;
}

_approve(sender, tokenManagerAddress, allowance_ + amount);
Expand Down
6 changes: 3 additions & 3 deletions contracts/test/InterchainTokenTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ contract InterchainTokenTest is InterchainToken, Distributable, IERC20BurnableMi
if (!tokenManagerRequiresApproval_) return;
address tokenManagerAddress = address(tokenManager_);
uint256 allowance_ = allowance[sender][tokenManagerAddress];
if (allowance_ != type(uint256).max) {
if (allowance_ > type(uint256).max - amount) {
allowance_ = type(uint256).max - amount;
if (allowance_ != UINT256_MAX) {
if (allowance_ > UINT256_MAX - amount) {
allowance_ = UINT256_MAX - amount;
}

_approve(sender, tokenManagerAddress, allowance_ + amount);
Expand Down
3 changes: 2 additions & 1 deletion contracts/token-implementations/ERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ contract ERC20 is IERC20 {
mapping(address => mapping(address => uint256)) public override allowance;

uint256 public override totalSupply;
uint256 internal constant UINT256_MAX = 2 ** 256 - 1;

/**
* @dev See {IERC20-transfer}.
Expand Down Expand Up @@ -79,7 +80,7 @@ contract ERC20 is IERC20 {
function transferFrom(address sender, address recipient, uint256 amount) external virtual override returns (bool) {
uint256 _allowance = allowance[sender][msg.sender];

if (_allowance != type(uint256).max) {
if (_allowance != UINT256_MAX) {
_approve(sender, msg.sender, _allowance - amount);
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/token-implementations/StandardizedToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import { Distributable } from '../utils/Distributable.sol';
contract StandardizedToken is IERC20BurnableMintable, InterchainToken, ERC20Permit, Implementation, Distributable {
using AddressBytesUtils for bytes;

address internal tokenManager_;
string public name;
string public symbol;
uint8 public decimals;
address internal tokenManager_;

bytes32 private constant CONTRACT_ID = keccak256('standardized-token');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
pragma solidity ^0.8.0;

import { TokenManager } from '../TokenManager.sol';
import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';
import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';

/**
* @title TokenManagerAddressStorage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ contract TokenManagerLiquidityPool is TokenManagerAddressStorage, NoReEntrancy {
*/
function _giveToken(address to, uint256 amount) internal override noReEntrancy returns (uint256) {
IERC20 token = IERC20(tokenAddress());
uint256 balance = IERC20(token).balanceOf(to);
uint256 balance = token.balanceOf(to);

SafeTokenTransferFrom.safeTransferFrom(token, liquidityPool(), to, amount);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ contract TokenManagerLockUnlockFee is TokenManagerAddressStorage, NoReEntrancy {
*/
function _giveToken(address to, uint256 amount) internal override noReEntrancy returns (uint256) {
IERC20 token = IERC20(tokenAddress());
uint256 balance = IERC20(token).balanceOf(to);
uint256 balance = token.balanceOf(to);

SafeTokenTransfer.safeTransfer(token, to, amount);

Expand Down

0 comments on commit 926e025

Please sign in to comment.