-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathExtsload.sol
More file actions
64 lines (60 loc) · 2.55 KB
/
Extsload.sol
File metadata and controls
64 lines (60 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IExtsload} from "./interfaces/IExtsload.sol";
/// @notice Enables public storage access for efficient state retrieval by external contracts.
/// https://eips.ethereum.org/EIPS/eip-2330#rationale
abstract contract Extsload is IExtsload {
/// @inheritdoc IExtsload
function extsload(bytes32 slot) external view returns (bytes32) {
assembly ("memory-safe") {
mstore(0, sload(slot))
return(0, 0x20)
}
}
/// @inheritdoc IExtsload
function extsload(bytes32 startSlot, uint256 nSlots) external view returns (bytes32[] memory) {
assembly ("memory-safe") {
let memptr := mload(0x40)
let start := memptr
// A left bit-shift of 5 is equivalent to multiplying by 32 but costs less gas.
let length := shl(5, nSlots)
// The abi offset of dynamic array in the returndata is 32.
mstore(memptr, 0x20)
// Store the length of the array returned
mstore(add(memptr, 0x20), nSlots)
// update memptr to the first location to hold a result
memptr := add(memptr, 0x40)
let end := add(memptr, length)
for {} 1 {} {
mstore(memptr, sload(startSlot))
memptr := add(memptr, 0x20)
startSlot := add(startSlot, 1)
if iszero(lt(memptr, end)) { break }
}
return(start, sub(end, start))
}
}
/// @inheritdoc IExtsload
function extsload(bytes32[] calldata slots) external view returns (bytes32[] memory) {
assembly ("memory-safe") {
let memptr := mload(0x40)
let start := memptr
// for abi encoding the response - the array will be found at 0x20
mstore(memptr, 0x20)
// next we store the length of the return array
mstore(add(memptr, 0x20), slots.length)
// update memptr to the first location to hold an array entry
memptr := add(memptr, 0x40)
// A left bit-shift of 5 is equivalent to multiplying by 32 but costs less gas.
let end := add(memptr, shl(5, slots.length))
let calldataptr := slots.offset
for {} 1 {} {
mstore(memptr, sload(calldataload(calldataptr)))
memptr := add(memptr, 0x20)
calldataptr := add(calldataptr, 0x20)
if iszero(lt(memptr, end)) { break }
}
return(start, sub(end, start))
}
}
}