forked from argotorg/fe
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathabi.fe
More file actions
76 lines (70 loc) · 2.73 KB
/
Copy pathabi.fe
File metadata and controls
76 lines (70 loc) · 2.73 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
65
66
67
68
69
70
71
72
73
74
75
76
/// Common Solidity ABI dynamic types and memory-backed byte views.
pub use core::abi::{Bytes, BytesView, DynArray, DynString, MemoryInput}
/// UTF-8 text stored as Solidity ABI `string`.
pub type Text = DynString
/// Solidity ABI dynamic array.
pub type Vec<T> = DynArray<T>
pub use sol::{self, *}
use super::evm::effects::RawMem
use super::evm::{mem, ops}
/// Allocate a 32-byte Solidity ABI `bytes` value from a single word.
///
/// The returned value owns a memory tail with layout `(len = 32, word)`.
/// Use this when an ABI `bytes` parameter or event field should contain one
/// full 32-byte chunk, for example a `bytes`-typed wrapper around a `bytes32`.
#[inline(always)]
pub fn bytes_from_word(_ w: u256) -> Bytes uses (mem: mut RawMem) {
let data = mem::alloc(64)
mem.mstore(addr: data, value: 32)
mem.mstore(addr: data + 32, value: w)
Bytes::from_abi_tail(data: data, len: 32, size: 64)
}
/// Allocate a Solidity ABI `bytes` value from `N` full 32-byte words.
///
/// The returned value has `len = N * 32` and stores the words verbatim in the
/// payload. Use `bytes_from_words_prefix` when the logical byte length is not
/// a whole number of words.
pub fn bytes_from_words<const N: usize>(_ words: [u256; N]) -> Bytes
uses (mem: mut RawMem)
{
let len: u256 = (N as u256) * 32
let size: u256 = 32 + len
let data = mem::alloc(size)
mem.mstore(addr: data, value: len)
let mut i: usize = 0
while i < N {
mem.mstore(addr: data + 32 + (i as u256) * 32, value: words[i])
i += 1
}
Bytes::from_abi_tail(data: data, len: len, size: size)
}
/// Allocate a `Bytes` of byte length `LEN` from `N` u256 words.
///
/// `LEN <= N * 32`; slack in the last canonical word is preserved in memory but
/// outside `LEN` is not part of the canonical value. Extra words beyond the
/// canonical padded length are ignored. The function reverts with empty
/// returndata when `LEN > N * 32`.
///
/// This is useful for fixed-size byte sequences that are passed through
/// Solidity ABI dynamic `bytes`, such as a 48-byte BLS public key backed by two
/// words.
pub fn bytes_from_words_prefix<const LEN: usize, const N: usize>(_ words: [u256; N]) -> Bytes
uses (mem: mut RawMem)
{
let len: u256 = LEN as u256
let capacity: u256 = (N as u256) * 32
if len > capacity {
ops::revert(offset: 0, len: 0)
}
let payload_words: usize = (LEN + 31) / 32
let payload: u256 = (payload_words as u256) * 32
let size: u256 = 32 + payload
let data = mem::alloc(size)
mem.mstore(addr: data, value: len)
let mut i: usize = 0
while i < payload_words {
mem.mstore(addr: data + 32 + (i as u256) * 32, value: words[i])
i += 1
}
Bytes::from_abi_tail(data: data, len: len, size: size)
}