Created
March 4, 2025 17:46
-
-
Save Turupawn/4947fad7b0ddbc38182ded18532d13d5 to your computer and use it in GitHub Desktop.
fe jam 4 marzo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mod std { | |
pub mod evm { | |
pub type Address = u256 | |
pub struct Wei { value: usize } | |
pub struct Ptr { pub location: usize } | |
pub struct Buf { pub offset: Ptr, pub len: usize } | |
const HASH_SCRATCH_OFFSET: u256 = 0x0 | |
extern { | |
pub fn __call(gas: Wei, address: Address, value: Wei, args: Buf, ret: Buf) | |
pub fn __mstore(_ loc: u256, _ data: u256) | |
pub fn __mload(_ loc: u256) -> u256 | |
pub fn __sstore(_ loc: u256, _ data: u256) | |
pub fn __sload(_ loc: u256) -> u256 | |
pub fn __keccak256(args: Buf) -> u256 | |
pub fn __caller() -> Address | |
pub fn __revert() | |
pub fn __sstore2(_ loc: StoragePtr, _ data: &[u8]) | |
} | |
pub fn alloc(len: usize) -> Buf { | |
// TODO: initialize the free memory pointer | |
let offset : usize //= __mload(0x40) as usize // 0 | |
let len : usize //= __mload(0x40) // 0 | |
// ... | |
let x = Buf { offset: Ptr { location: offset }, len: len} | |
x | |
} | |
} | |
} | |
extern { | |
fn as_u8(_ value: u256) -> u8 | |
} | |
pub trait IntDowncast<To> { | |
fn truncating_cast(self) -> To | |
fn saturating_cast(self) -> To // 0x01000000000000000000000 -> 0xff 0x00 | |
fn try_cast(self) -> Option<To> | |
} | |
impl IntDowncast<u32> for u256 { | |
fn truncating_cast(self) -> u32 { | |
let bytes: [u8; 32] = self.as_bytes() | |
u32::from_be_bytes(bytes[29..=32]) | |
} | |
fn saturating_cast(self) -> u32 { | |
} | |
fn try_cast(self) -> Option<To> { | |
} | |
} | |
pub trait Decode { | |
fn decode(data: u256) -> Self | |
} | |
pub trait Encode { | |
fn encode(data: u256) -> Self | |
fn encode_size() -> usize | |
} | |
impl Decode for u256 { | |
fn decode(data: u256) -> u256 { | |
std::evm::__mload(data) // Load the u256 value from storage | |
} | |
} | |
impl Encode for u256 { | |
fn encode(data: u256) -> u256 { | |
std::evm::__mload(data) // Load the u256 value from storage | |
} | |
fn encode_size() -> usize { | |
32 | |
} | |
} | |
impl Decode for (u256, u256) { | |
fn decode(data: u256) -> (u256, u256) { | |
let x =std::evm::__mload(data) // Load the u256 value from storage | |
(x,x) | |
} | |
} | |
impl Encode for (u256, u256) { | |
fn encode(data: u256) -> (u256, u256) { | |
let x =std::evm::__mload(data) // Load the u256 value from storage | |
(x,x) | |
} | |
fn encode_size() -> usize { | |
64 | |
} | |
} | |
trait Store { | |
fn load(_ offset: u256) -> Self | |
fn store(self, _ offset: u256) | |
} | |
impl Store for (u256, u256) { | |
fn load(_ s: StorageSlice) -> Self { | |
(s.get(0), s.get(1)) | |
} | |
fn load(_ offset: u256) -> Self { | |
let a = std::evm::__sload(offset) | |
let b = std::evm::__sload(offset + 1) | |
(a, b) | |
} | |
fn store(self, _ offset: u256) { | |
std::evm::__sstore(offset, self.0) | |
std::evm::__sstore(offset + 1, self.1) | |
} | |
} | |
impl<T, U> Map<T, U> | |
where T: Encode, U: Store | |
{ | |
pub fn get(self, _ key: T) -> U { | |
let slot_size : usize = 32 | |
let allocated_buffer = std::evm::alloc(len: T::encode_size() + slot_size) | |
let key_encoded : u256// = T::encode(key) | |
let mut location : u256// = allocated_buffer.offset.location | |
let _slot : u256// = self.slot.as_u256() | |
let value_encoded : u256// = U::encode(value) | |
std::evm::__mstore(location, key_encoded) | |
location += 32 | |
std::evm::__mstore(location, _slot) | |
let location_usize : usize// = location as usize TODO | |
let value_location : u256 = std::evm::__keccak256( | |
args: std::evm::Buf { | |
offset: std::evm::Ptr { | |
location: location_usize | |
}, | |
len: slot_size + T::encode_size() | |
} | |
) | |
U::load(StorageSlice { offset: value_location, words: 2 }) | |
let mut _return_value : U// = return_value.into() // TODO: convert to U | |
_return_value | |
} | |
pub fn set(self, _ key: T, _ value: U) { | |
} | |
} | |
struct Map<T, U> { | |
slot: u8, | |
} | |
contract ERC20 { | |
pub balance: Map<std::evm::Address, u256>, | |
pub allowance: Map<(std::evm::Address, std::evm::Address), std::evm::Address>, | |
pub TOTAL_SUPPLY: u256, | |
pub NAME: String<20>, | |
pub SYMBOL: String<5>, | |
pub DECIMALS: u8 | |
} | |
impl ERC20 { | |
pub fn constructor(mut self) { | |
// TODO: use native constructor | |
self.TOTAL_SUPPLY = 21_000_000 * 1**18 | |
self.balance.set(std::evm::__caller(), self.TOTAL_SUPPLY) | |
} | |
pub fn name(self) -> String<20> { | |
self.NAME | |
} | |
pub fn symbol(self) -> String<5> { | |
self.SYMBOL | |
} | |
pub fn decimals(self) -> u8 { | |
self.DECIMALS | |
} | |
pub fn totalSupply(self) -> u256 { | |
self.TOTAL_SUPPLY | |
} | |
pub fn balanceOf(self, account : std::evm::Address) -> u256 { | |
self.balance.get(account) | |
} | |
pub fn transfer(mut self, to : std::evm::Address, value : u256) -> bool { | |
if self.balance.get(std::evm::__caller()) < value { | |
std::evm::__revert() | |
} | |
self.balance.set(std::evm::__caller(), self.balance.get(std::evm::__caller()) - value) | |
self.balance.set(to, self.balance.get(to) + value) | |
true | |
} | |
pub fn allowance(self, owner : std::evm::Address, spender : std::evm::Address) -> u256 { | |
self.allowance.get((owner, spender)) | |
} | |
pub fn approve(mut self, spender : std::evm::Address, value : u256) -> bool { | |
self.allowance.set((std::evm::__caller(), spender), value) | |
true | |
} | |
pub fn transferFrom(mut self, from : std::evm::Address, to : std::evm::Address, value : u256) -> bool { | |
if (self.allowance.get((from, std::evm::__caller())) < value || self.balance.get(from) < value) { | |
std::evm::__revert() | |
} | |
self.allowance.set((from, std::evm::__caller()), self.allowance.get((from, std::evm::__caller())) - value) | |
self.balance.set(from, self.balance.get(from) - value) | |
self.balance.set(to, self.balance.get(to) + value) | |
true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment