Skip to content

Instantly share code, notes, and snippets.

@Turupawn
Created March 4, 2025 17:46
Show Gist options
  • Save Turupawn/4947fad7b0ddbc38182ded18532d13d5 to your computer and use it in GitHub Desktop.
Save Turupawn/4947fad7b0ddbc38182ded18532d13d5 to your computer and use it in GitHub Desktop.
fe jam 4 marzo
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