EIP-2929 in Berlin fork increased the gas costs of SLOADs and CALL* family opcodes increasing them for not-accessed slots/addresses and decreasing them for accessed slots. EIP-2930 optionally supports specifying an access list in the transition of all slots and addresses accessed by the transaction which reduces their gas cost upon access and prevents EIP-2929 gas cost increases from breaking contracts.
Impact: Considering these changes may significantly impact gas usage for transactions that call functions touching many state variables or making many external calls.
Example 1: Commonly used functions depositTo() and withdraw*() which cost 0.5M gas now can use access lists for all the state variables they touch and addresses of calls made to reduce gas.
Example 2: Functions such as sweepTimelockBalances() which potentially touch many state variables for multiple users and also make multiple transfers may benefit significantly by considering the use of access lists.
Example 3: awardExternalERC721() makes CALLs to externalToken contract which costs 2600 first time and then 100 subsequently. By including this in an access list (per Berlin EIP-2930), we can reduce the cost of the first CALL to externalToken contract from 2600 to 2400 (cost of specifying the address in the access list) + 100 (subsequent CALL which is cheaper now because it is considered as accessed due to the access list inclusion). So it is 2500 instead of 2600 and we save 100 gas.
This may or may not help with gas consumption, but it is deeply unmaintainable. While this might introduce improvements we're not going to tackle this.
Handle
0xRajeev
Vulnerability details
Impact
EIP-2929 in Berlin fork increased the gas costs of SLOADs and CALL* family opcodes increasing them for not-accessed slots/addresses and decreasing them for accessed slots. EIP-2930 optionally supports specifying an access list in the transition of all slots and addresses accessed by the transaction which reduces their gas cost upon access and prevents EIP-2929 gas cost increases from breaking contracts.
Impact: Considering these changes may significantly impact gas usage for transactions that call functions touching many state variables or making many external calls.
Example 1: Commonly used functions depositTo() and withdraw*() which cost 0.5M gas now can use access lists for all the state variables they touch and addresses of calls made to reduce gas.
Example 2: Functions such as sweepTimelockBalances() which potentially touch many state variables for multiple users and also make multiple transfers may benefit significantly by considering the use of access lists.
Example 3: awardExternalERC721() makes CALLs to externalToken contract which costs 2600 first time and then 100 subsequently. By including this in an access list (per Berlin EIP-2930), we can reduce the cost of the first CALL to externalToken contract from 2600 to 2400 (cost of specifying the address in the access list) + 100 (subsequent CALL which is cheaper now because it is considered as accessed due to the access list inclusion). So it is 2500 instead of 2600 and we save 100 gas.
Proof of Concept
https://eips.ethereum.org/EIPS/eip-2929
https://eips.ethereum.org/EIPS/eip-2930
https://hackmd.io/@fvictorio/gas-costs-after-berlin
https://github.com/gakonst/ethers-rs/issues/265
https://github.com/code-423n4/2021-06-pooltogether/blob/85f8d044e7e46b7a3c64465dcd5dffa9d70e4a3e/contracts/PrizePool.sol#L623-L683
https://github.com/code-423n4/2021-06-pooltogether/blob/85f8d044e7e46b7a3c64465dcd5dffa9d70e4a3e/contracts/PrizePool.sol#L601-L603
Tools Used
Manual Analysis
Recommended Mitigation Steps
Evaluate the feasibility of using access lists to save gas due to EIPs 2929 & 2930 post-Berlin hard fork. The tooling support is WIP.