Platform: Code4rena
Start Date: 20/01/2023
Pot Size: $90,500 USDC
Total HM: 10
Participants: 59
Period: 7 days
Judge: Picodes
Total Solo HM: 4
Id: 206
League: ETH
Rank: 21/59
Findings: 2
Award: $261.29
š Selected for report: 0
š Solo Findings: 0
š Selected for report: RaymondFam
Also found by: Rolezn, SaeedAlipoor01988, kaden, mert_eren, nadin, pavankv, rbserver
212.7503 USDC - $212.75
https://github.com/code-423n4/2023-01-timeswap/blob/ef4c84fb8535aad8abd6b67cc45d994337ec4514/packages/v2-option/src/structs/Option.sol#L103 https://github.com/code-423n4/2023-01-timeswap/blob/ef4c84fb8535aad8abd6b67cc45d994337ec4514/packages/v2-option/src/structs/Option.sol#L141
Accounting in Timeswap functions along the assumption that the balances of tokens will not change. However, there are many tokens whose balance changes within the account in which they're being held, e.g. Aave aTokens balance will increase as they accrue interest. We can see this assumption being a problem with e.g. the option logic:
// Option.sol::mint() option.totalLong0 += token0AndLong0Amount;
We can see above that in the mint function, we increment totalLong0
by the amount which the user must send in to the contract.
Note that token0AndLong0Amount
in mint() and burn() is the amount which the user sends and receives respectively.
Later on when we go to burn our options for the underlying tokens, we see we can not receive more than totalLong0
, thereby locking any additional tokens in the contract.
// Option.sol::burn() option.totalLong0 -= token0AndLong0Amount;
#0 - c4-judge
2023-02-02T22:24:51Z
Picodes marked the issue as duplicate of #52
#1 - c4-judge
2023-02-12T22:37:35Z
Picodes marked the issue as satisfactory
š Selected for report: 0xSmartContract
Also found by: 0x1f8b, 0xackermann, Aymen0909, Beepidibop, IllIllI, Iurii3, Rageur, RaymondFam, ReyAdmirado, Rolezn, SaeedAlipoor01988, Udsen, Viktor_Cortess, W0RR1O, W_Max, atharvasama, c3phas, chaduke, descharre, fatherOfBlocks, kaden, matrix_0wl, shark
48.5424 USDC - $48.54
When safecasting, a check is performed to ensure that the value being cast is not greater than the max value of the type it's being cast to before casting:
function toUint16(uint256 value) internal pure returns (uint16 result) { if (value > type(uint16).max) revert Uint16Overflow(); result = uint16(value); }
We can more efficiently perform this check as follows:
function toUint16(uint256 value) internal pure returns (uint16 result) { if ((result = uint16(value)) != value) revert Uint16Overflow(); }
Whenever a new pool is initialized, if it doesn't already exist within the listOfPools
array, it gets pushed. Because we're updating storage, maintaining this array of pools adds significant gas overhead to the cost of initializing new pools. Since this array is only used for indexing, we can save gas by indexing pools off-chain instead.
The same issue exists for the listOfOptions
array.
uint256
to represent ReentrancyGuard
stateIn the ReentrancyGuard
library, the current state is represented by a uint96
. This can be replaced with a uint256
to save gas since the EVM works with 256 bit words and requires more computation to work with smaller types.
TimeswapV2Pool
methodsAs noted in above context, several methods in TimeswapV2Pool
enforce that the pool has liquidity, before later redundantly checking again whether the pool has liquidity.
You can mark public or external functions as payable to save gas. Functions that are not payable have additional logic to check if there was a value sent with a call, however, making a function payable eliminates this check. This optimization should be carefully considered due to potentially unwanted behavior when a function does not need to accept ether.
contract GasTest is DSTest { Contract0 c0; Contract1 c1; function setUp() public { c0 = new Contract0(); c1 = new Contract1(); } function testGas() public { c0.isNotPayable(); c1.isPayable(); } } contract Contract0 { function isNotPayable() public view { uint256 val = 0; val++; } } contract Contract1 { function isPayable() public payable { uint256 val = 0; val++; } }
āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract0 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 32081 ā 190 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā isNotPayable ā 198 ā 198 ā 198 ā 198 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract1 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 29681 ā 178 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā isPayable ā 174 ā 174 ā 174 ā 174 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāāāÆ
constant
if they never change.State variables can be declared as constant or immutable. In both cases, the variables cannot be modified after the contract has been constructed. For constant variables, the value has to be fixed at compile-time, while for immutable, it can still be assigned at construction time.
The compiler does not reserve a storage slot for these variables, and every occurrence is inlined by the respective value.
Compared to regular state variables, the gas costs of constant and immutable variables are much lower. For a constant variable, the expression assigned to it is copied to all the places where it is accessed and also re-evaluated each time. This allows for local optimizations. Immutable variables are evaluated once at construction time and their value is copied to all the places in the code where they are accessed. For these values, 32 bytes are reserved, even if they would fit in fewer bytes. Due to this, constant values can sometimes be cheaper than immutable values.
contract GasTest is DSTest { Contract0 c0; Contract1 c1; Contract2 c2; function setUp() public { c0 = new Contract0(); c1 = new Contract1(); c2 = new Contract2(); } function testGas() public view { c0.addValue(); c1.addImmutableValue(); c2.addConstantValue(); } } contract Contract0 { uint256 val; constructor() { val = 10000; } function addValue() public view { uint256 newVal = val + 1000; } } contract Contract1 { uint256 immutable val; constructor() { val = 10000; } function addImmutableValue() public view { uint256 newVal = val + 1000; } } contract Contract2 { uint256 constant val = 10; function addConstantValue() public view { uint256 newVal = val + 1000; } }
āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāāā¬āāāāāāāāā¬āāāāāāā¬āāāāāāāāāā® ā Contract0 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāāŖāāāāāāāāāŖāāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāāā¼āāāāāāāāā¼āāāāāāā¼āāāāāāāāā⤠ā 54593 ā 198 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāāā¼āāāāāāāāā¼āāāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāāā¼āāāāāāāāā¼āāāāāāā¼āāāāāāāāā⤠ā addValue ā 2302 ā 2302 ā 2302 ā 2302 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāāā“āāāāāāāāā“āāāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract1 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 38514 ā 239 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā addImmutableValue ā 199 ā 199 ā 199 ā 199 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract2 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 32287 ā 191 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā addConstantValue ā 199 ā 199 ā 199 ā 199 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāāāÆ
Use assembly for math instead of Solidity. You can check for overflow/underflow in assembly to ensure safety. If using Solidity versions < 0.8.0 and you are using Safemath, you can gain significant gas savings by using assembly to calculate values and checking for overflow/underflow.
contract GasTest is DSTest { Contract0 c0; Contract1 c1; Contract2 c2; Contract3 c3; Contract4 c4; Contract5 c5; Contract6 c6; Contract7 c7; function setUp() public { c0 = new Contract0(); c1 = new Contract1(); c2 = new Contract2(); c3 = new Contract3(); c4 = new Contract4(); c5 = new Contract5(); c6 = new Contract6(); c7 = new Contract7(); } function testGas() public { c0.addTest(34598345, 100); c1.addAssemblyTest(34598345, 100); c2.subTest(34598345, 100); c3.subAssemblyTest(34598345, 100); c4.mulTest(34598345, 100); c5.mulAssemblyTest(34598345, 100); c6.divTest(34598345, 100); c7.divAssemblyTest(34598345, 100); } } contract Contract0 { //addition in Solidity function addTest(uint256 a, uint256 b) public pure { uint256 c = a + b; } } contract Contract1 { //addition in assembly function addAssemblyTest(uint256 a, uint256 b) public pure { assembly { let c := add(a, b) if lt(c, a) { mstore(0x00, "overflow") revert(0x00, 0x20) } } } } contract Contract2 { //subtraction in Solidity function subTest(uint256 a, uint256 b) public pure { uint256 c = a - b; } } contract Contract3 { //subtraction in assembly function subAssemblyTest(uint256 a, uint256 b) public pure { assembly { let c := sub(a, b) if gt(c, a) { mstore(0x00, "underflow") revert(0x00, 0x20) } } } } contract Contract4 { //multiplication in Solidity function mulTest(uint256 a, uint256 b) public pure { uint256 c = a * b; } } contract Contract5 { //multiplication in assembly function mulAssemblyTest(uint256 a, uint256 b) public pure { assembly { let c := mul(a, b) if lt(c, a) { mstore(0x00, "overflow") revert(0x00, 0x20) } } } } contract Contract6 { //division in Solidity function divTest(uint256 a, uint256 b) public pure { uint256 c = a * b; } } contract Contract7 { //division in assembly function divAssemblyTest(uint256 a, uint256 b) public pure { assembly { let c := div(a, b) if gt(c, a) { mstore(0x00, "underflow") revert(0x00, 0x20) } } } }
āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract0 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 40493 ā 233 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā addTest ā 303 ā 303 ā 303 ā 303 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract1 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 37087 ā 216 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā addAssemblyTest ā 263 ā 263 ā 263 ā 263 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract2 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 40293 ā 232 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā subTest ā 300 ā 300 ā 300 ā 300 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract3 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 37287 ā 217 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā subAssemblyTest ā 263 ā 263 ā 263 ā 263 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract4 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 41893 ā 240 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā mulTest ā 325 ā 325 ā 325 ā 325 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract5 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 37087 ā 216 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā mulAssemblyTest ā 265 ā 265 ā 265 ā 265 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract6 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 41893 ā 240 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā divTest ā 325 ā 325 ā 325 ā 325 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract7 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 37287 ā 217 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā divAssemblyTest ā 265 ā 265 ā 265 ā 265 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāāāÆ
contract GasTest is DSTest { Contract0 c0; Contract1 c1; function setUp() public { c0 = new Contract0(); c1 = new Contract1(); } function testGas() public view { c0.solidityHash(2309349, 2304923409); c1.assemblyHash(2309349, 2304923409); } } contract Contract0 { function solidityHash(uint256 a, uint256 b) public view { //unoptimized keccak256(abi.encodePacked(a, b)); } } contract Contract1 { function assemblyHash(uint256 a, uint256 b) public view { //optimized assembly { mstore(0x00, a) mstore(0x20, b) let hashedVal := keccak256(0x00, 0x40) } } }
āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract0 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 36687 ā 214 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā solidityHash ā 313 ā 313 ā 313 ā 313 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāā⯠āāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāā¬āāāāāā¬āāāāāāāāā¬āāāāāā¬āāāāāāāāāā® ā Contract1 contract ā ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāāŖāāāāāāāāāāāāāāāāāāŖāāāāāāŖāāāāāāāāāŖāāāāāāŖāāāāāāāāāā” ā Deployment Cost ā Deployment Size ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā 31281 ā 186 ā ā ā ā ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā Function Name ā min ā avg ā median ā max ā # calls ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā¼āāāāāā¼āāāāāāāāā¼āāāāāā¼āāāāāāāāā⤠ā assemblyHash ā 231 ā 231 ā 231 ā 231 ā 1 ā ā°āāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāā“āāāāāā“āāāāāāāāā“āāāāāā“āāāāāāāāāāÆ
#0 - c4-judge
2023-02-02T12:19:04Z
Picodes marked the issue as grade-b