Alchemix contest - _Adam's results

A protocol for self-repaying loans with no liquidation risk.

General Information

Platform: Code4rena

Start Date: 05/05/2022

Pot Size: $125,000 DAI

Total HM: 17

Participants: 62

Period: 14 days

Judge: leastwood

Total Solo HM: 15

Id: 120

League: ETH

Alchemix

Findings Distribution

Researcher Performance

Rank: 54/62

Findings: 1

Award: $91.84

๐ŸŒŸ Selected for report: 0

๐Ÿš€ Solo Findings: 0

G[01] Default values

When initizalising a variable to the default value it can be left blank to save some gas.

FuseTokenAdapterV1.sol#L36 to: uint256 private constant NO_ERROR;

AlchemistV2.sol#L1458 to: uint256 totalValue;

EthAssetManager.sol#L566 to uint256 total;

TransmuterV2.sol#L96 to address public constant ZERO_ADDRESS;

G[02] For Loop Optimisations

For loops can be optimised a few ways: - i can be left blank as 0 is the default value and doesnโ€™t need to be assigned - The length can be cached to the stack rather than be called every loop (saves roughly 3 gas per iteration or 97 in the instances where a storage variables length is being looped over.) - ++i can be used instead of i++ as it saves a temp variable being created every iteration (will save roughly 5 gas per iteration.)

As an example the for loop on line 141 in CrossChainCanonicalBase.sol would go from: 141 for (uint i = 0; i < bridgeTokensArray.length; i++) {

to: 141 uint256 bridgeTokensArrayLength = bridgeTokensArray.length; 142 for(uint i; i < bridgeTokensArrayLength; ++i) {

Multicall.sol#L14 AlchemistV2.sol#L990 AlchemistV2.sol#L1282 AlchemistV2.sol#L1355 AlchemistV2.sol#L1461 AlchemistV2.sol#L1524 CrossChainCanonicalBase.sol#L57 CrossChainCanonicalBase.sol#L141 EthAssetManager.sol#L567 StakingPools.sol#L188 ThreePoolAssetManager.sol#L250 ThreePoolAssetManager.sol#L254 ThreePoolAssetManager.sol#L353 ThreePoolAssetManager.sol#L773 ThreePoolAssetManager.sol#L902 TransmuterBuffer.sol#L172 TransmuterBuffer.sol#L186 TransmuterBuffer.sol#L235 TransmuterBuffer.sol#L242 TransmuterBuffer.sol#L272 TransmuterBuffer.sol#L382 TransmuterBuffer.sol#L387 TransmuterBuffer.sol#L479

G[03] Emitting Storage Variables

Here, you can emit the memory values as opposed to reading from storage. (save roughly 97 gas every time the event is emitted.)

AlchemicTokenV2Base.sol#L100 to: emit SetFlashMintFee(newFee);

AlchemicTokenV2.sol#L94 to: emit SetFlashMintFee(newFee);

AlchemistV2.sol#L272-L276 to: emit AdminUpdated(params.admin); emit TransmuterUpdated(params.transmuter); emit MinimumCollateralizationUpdated(params.minimumCollateralization); emit ProtocolFeeUpdated(params.protocolFee); emit ProtocolFeeReceiverUpdated(params.protocolFeeReceiver);

TransmuterBuffer.sol#L247 to: emit SetAlchemist(_alchemist);

TransmuterV2.sol#L203 to: emit Paused(pauseState);

G[04] Minimizing SLOADs

Whenever reading a storage variable more than once in a given scope it is cheaper to store in memory (100 gas per SLOAD vs 100 gas SSTORE and 3 gas MSTORE/3 gas for each MLOAD)

pendingAdmin is read 3 times in the following places. AlchemistV2.sol#L289-L295 EthAssetManager.sol#L304-L312 ThreePoolAssetManager.sol#L456-L464

transmuter is read twice in the following places. AlchemistV2.sol#L792-L795 AlchemistV2.sol#L876-L879 AlchemistV2.sol#L942-L945

rewardReceiver is read twice in the following places. EthAssetManager.sol#L698-L699 ThreePoolAssetManager.sol#L632-L633

poolId & exchangeRate are read twice. gALCX.sol#L71-L79

If line 133 is moved to above 131, _pendingGovernance can be used in the require statement saving an SLOAD. Would cost an extra 6 gas whenever the require statement fails, but would save 93 gas everytime the function is called successfully. StakingPools.sol#L131-L133

transmuterBuffer is read twice. ThreePoolAssetManager.sol#L719-L721

alchemist is read 3 times in the following places. TransmuterBuffer.sol#L443-L446

TransmuterBuffer.sol#L513-L522

flowAvailable[underlyingToken] can be read up to 5 times. TransmuterBuffer.sol#L536-L551

amos[underlyingToken] is read twice. TransmuterBuffer.sol#L567-L568

sinkTransmuter and token are both read twice TransmuterConduit.sol#L35-L36

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax ยฉ 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter