multiplexer-evm 0.1.1

A Rust library and Solidity contracts for building and executing complex EVM transaction sequences, including flash loans.
Documentation
use alloy_primitives::{Address, U256};

// Operation opcodes as constants
pub const OP_EOF: u8 = 0x00;
pub const OP_CLEARDATA: u8 = 0x01;
pub const OP_SETDATA: u8 = 0x02;
pub const OP_SETADDR: u8 = 0x03;
pub const OP_SETVALUE: u8 = 0x04;
pub const OP_EXTCODECOPY: u8 = 0x05;
pub const OP_CALL: u8 = 0x06;
pub const OP_CREATE: u8 = 0x07;
pub const OP_DELEGATECALL: u8 = 0x08;
pub const OP_SETCALLBACK: u8 = 0x09;
pub const OP_SETFAIL: u8 = 0x0a;
pub const OP_CLEARFAIL: u8 = 0x0b;


// Struct for the CLEARDATA operation
pub struct ClearData {
    pub size: u16,
}

impl ClearData {
    pub fn new(size: u16) -> Self {
        ClearData { size }
    }

    pub fn encode(&self) -> Vec<u8> {
        let mut encoded = Vec::new();
        encoded.push(OP_CLEARDATA); // Opcode
        encoded.extend(&self.size.to_be_bytes()); // Size
        encoded
    }
}

// Struct for the SETDATA operation
pub struct SetData {
    pub offset: u16,
    pub data: Vec<u8>,
}

impl SetData {
    pub fn new(offset: u16, data: Vec<u8>) -> Self {
        SetData { offset, data }
    }

    pub fn encode(&self) -> Vec<u8> {
        let data_size = self.data.len() as u16;
        let mut encoded = Vec::new();
        encoded.push(OP_SETDATA); // Opcode
        encoded.extend(&self.offset.to_be_bytes()); // Offset
        encoded.extend(&data_size.to_be_bytes()); // Data Size
        encoded.extend(&self.data); // Data

        encoded
    }
}

// Struct for the SETADDR operation
pub struct SetAddr {
    pub addr: Address, // 20-byte address
}

impl SetAddr {
    pub fn new(addr: Address) -> Self {
        SetAddr { addr }
    }

    pub fn encode(&self) -> Vec<u8> {
        let mut encoded = Vec::new();
        encoded.push(OP_SETADDR); // Opcode
        encoded.extend(&self.addr); // Address
        encoded
    }
}

// Struct for the SETVALUE operation
#[derive(Clone, Debug)]
pub struct SetValue {
    pub value: U256,
}

impl SetValue {
    pub fn new(value: U256) -> Self {
        SetValue { value }
    }

    pub fn encode(&self) -> Vec<u8> {
        let mut encoded = Vec::new();
        encoded.push(OP_SETVALUE); // Opcode
        encoded.extend(&self.value.to_be_bytes::<32>()); // Value
        encoded
    }
}

// Struct for the EXTCODECOPY operation
pub struct ExtCodeCopy {
    pub source: Address,  // Address of contract to copy code from
    pub data_offset: u16, // Offset in the data to copy the code to
    pub code_offset: u16, // Offset in the code to copy from
    pub size: u16,        // Size of the code to copy
}

impl ExtCodeCopy {
    pub fn new(source: Address, data_offset: u16, code_offset: u16, size: u16) -> Self {
        ExtCodeCopy {
            source,
            data_offset,
            code_offset,
            size,
        }
    }

    pub fn encode(&self) -> Vec<u8> {
        let mut encoded = Vec::new();
        encoded.push(OP_EXTCODECOPY); // Opcode
        encoded.extend(&self.source); // Source address
        encoded.extend(&self.data_offset.to_be_bytes()); // Offset
        encoded.extend(&self.code_offset.to_be_bytes()); // Offset
        encoded.extend(&self.size.to_be_bytes()); // Size
        encoded
    }
}

// Struct for the CALL operation
#[derive(Default)]
pub struct Call {}

impl Call {
    pub fn new() -> Self {
        Call {}
    }

    pub fn encode(&self) -> Vec<u8> {
        vec![OP_CALL] // Opcode
    }
}

// Struct for the CREATE operation
#[derive(Default)]
pub struct Create {
    pub created_address: Address,
}

impl Create {
    pub fn new(created_address: Address) -> Self {
        Self { created_address }
    }

    pub fn encode(&self) -> Vec<u8> {
        vec![OP_CREATE] // Opcode
    }
}

// Struct for the DELEGATECALL operation
#[derive(Default)]
pub struct DelegateCall {}

impl DelegateCall {
    pub fn new() -> Self {
        DelegateCall {}
    }

    pub fn encode(&self) -> Vec<u8> {
        vec![OP_DELEGATECALL] // Opcode
    }
}

// Struct for the SETCALLBACK operation
#[derive(Default)]
pub struct SetCallback {
    pub callback_address: Address
}

impl SetCallback {
    pub fn new(callback_address: Address) -> Self {
        SetCallback {callback_address}
    }

    pub fn encode(&self) -> Vec<u8> {
        let mut encoded = vec![OP_SETCALLBACK]; // Opcode
        encoded.extend(&self.callback_address); // Offset
        encoded
    }
}

// Struct for the SETFAIL operation
#[derive(Default)]
pub struct SetFail {}

impl SetFail {
    pub fn new() -> Self {
        SetFail {}
    }

    pub fn encode(&self) -> Vec<u8> {
        vec![OP_SETFAIL] // Opcode
    }
}

// Struct for the CLEARFAIL operation
#[derive(Default)]
pub struct ClearFail {}

impl ClearFail {
    pub fn new() -> Self {
        ClearFail {}
    }

    pub fn encode(&self) -> Vec<u8> {
        vec![OP_CLEARFAIL] // Opcode
    }
}