-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathExtsload.sol
44 lines (40 loc) · 1.72 KB
/
Extsload.sol
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
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright (C) 2024 PancakeSwap
pragma solidity ^0.8.0;
/// @notice This code is adapted from
// https://github.com/RageTrade/core/blob/main/contracts/utils/Extsload.sol
import {IExtsload} from "./interfaces/IExtsload.sol";
/// @notice Allows the inheriting contract make it's state accessable to other contracts
/// https://ethereum-magicians.org/t/extsload-opcode-proposal/2410/11
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[] 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))
}
}
}