-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: add versioned erc20 call for
felt252
symbols
- Loading branch information
Showing
11 changed files
with
196 additions
and
5 deletions.
There are no files selected for viewing
Empty file.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
pub(crate) mod store_packing_contract; | ||
pub(crate) mod erc20_felt252; | ||
pub(crate) mod erc20_bytearray; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#[starknet::interface] | ||
pub trait IERC20ByteArray<TContractState> { | ||
fn name(self: @TContractState) -> ByteArray; | ||
fn symbol(self: @TContractState) -> ByteArray; | ||
} | ||
|
||
#[starknet::contract] | ||
pub mod ERC20ByteArray { | ||
use super::IERC20ByteArray; | ||
use starknet::ContractAddress; | ||
|
||
#[storage] | ||
struct Storage { | ||
name: ByteArray, | ||
symbol: ByteArray, | ||
} | ||
|
||
#[constructor] | ||
fn constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray) { | ||
self.name.write(name); | ||
self.symbol.write(symbol); | ||
} | ||
|
||
#[abi(embed_v0)] | ||
impl ERC20ByteArray of IERC20ByteArray<ContractState> { | ||
fn name(self: @ContractState) -> ByteArray { | ||
self.name.read() | ||
} | ||
|
||
fn symbol(self: @ContractState) -> ByteArray { | ||
self.symbol.read() | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#[starknet::interface] | ||
pub trait IERC20Felt252<TContractState> { | ||
fn name(self: @TContractState) -> felt252; | ||
fn symbol(self: @TContractState) -> felt252; | ||
} | ||
|
||
#[starknet::contract] | ||
pub mod ERC20Felt252 { | ||
use super::IERC20Felt252; | ||
use starknet::ContractAddress; | ||
|
||
#[storage] | ||
struct Storage { | ||
name: felt252, | ||
symbol: felt252, | ||
} | ||
|
||
#[constructor] | ||
fn constructor(ref self: ContractState, name: felt252, symbol: felt252) { | ||
self.name.write(name); | ||
self.symbol.write(symbol); | ||
} | ||
|
||
#[abi(embed_v0)] | ||
impl ERC20Felt252 of IERC20Felt252<ContractState> { | ||
fn name(self: @ContractState) -> felt252 { | ||
self.name.read() | ||
} | ||
|
||
fn symbol(self: @ContractState) -> felt252 { | ||
self.symbol.read() | ||
} | ||
} | ||
} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
pub mod IReversionStrategy; | ||
pub mod IVaultToken; | ||
pub mod IERC20Metadata; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#[starknet::interface] | ||
pub trait IERC20MetadataFelt252<TContractState> { | ||
fn name(self: @TContractState) -> felt252; | ||
fn symbol(self: @TContractState) -> felt252; | ||
} | ||
|
||
#[starknet::interface] | ||
pub trait IERC20MetadataByteArray<TContractState> { | ||
fn name(self: @TContractState) -> ByteArray; | ||
fn symbol(self: @TContractState) -> ByteArray; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
pub mod trend_math; | ||
pub mod erc20_versioned_call; | ||
pub(crate) mod store_packing; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Core lib imports. | ||
use starknet::ContractAddress; | ||
use starknet::syscalls::{replace_class_syscall, deploy_syscall, call_contract_syscall}; | ||
|
||
// Local imports. | ||
use haiko_strategy_reversion::interfaces::IERC20Metadata::{ | ||
IERC20MetadataFelt252Dispatcher, IERC20MetadataFelt252DispatcherTrait | ||
}; | ||
|
||
// Fetch the symbol of an ERC20 token. | ||
// Older ERC20 tokens use `felt252` symbols, whereas newer ones use `ByteArray`. | ||
// This function examines the length of the returned array from `call_contract_syscall` | ||
// to handle both cases. | ||
// | ||
// # Arguments | ||
// * `contract_address` - address of ERC20 token | ||
// * `selector` - erc20 entry point selector | ||
pub fn get_symbol(contract_address: ContractAddress) -> ByteArray { | ||
let result = call_contract_syscall( | ||
contract_address, selector!("symbol"), ArrayTrait::<felt252>::new().span() | ||
) | ||
.unwrap(); | ||
let length = result.len(); | ||
let mut name: ByteArray = ""; | ||
// Switch between cases based on the length of the result array. | ||
// If the length is 1, then the symbol is a `felt252`. | ||
// If the length is greater than 1, then the symbol is a `ByteArray`. | ||
if length == 1 { | ||
let mut byte_array: ByteArray = ""; | ||
byte_array.append_word(*result.at(0), 31); | ||
let mut i = 0; | ||
loop { | ||
if i == byte_array.len() { | ||
break; | ||
} | ||
let byte = byte_array.at(i).unwrap(); | ||
if byte != 0 { | ||
name.append_byte(byte); | ||
} | ||
i += 1; | ||
}; | ||
} else { | ||
let pending_word_len: u32 = (*result.at(length - 1)).try_into().unwrap(); | ||
let mut i = 1; | ||
loop { | ||
if i == length - 1 { | ||
break; | ||
} | ||
let word = *result.at(i); | ||
let word_len = if i == length - 2 { | ||
pending_word_len | ||
} else { | ||
31 | ||
}; | ||
name.append_word(word, word_len); | ||
i += 1; | ||
}; | ||
} | ||
name | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub(crate) mod helpers; | ||
pub(crate) mod test_strategy; | ||
pub(crate) mod test_store_packing; | ||
pub(crate) mod test_erc20_interface; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Core lib imports. | ||
use starknet::ContractAddress; | ||
use starknet::syscalls::{deploy_syscall, call_contract_syscall}; | ||
use core::to_byte_array::{FormatAsByteArray, AppendFormattedToByteArray}; | ||
|
||
// Local imports. | ||
use haiko_strategy_reversion::contracts::mocks::{ | ||
erc20_bytearray::{IERC20ByteArrayDispatcher, IERC20ByteArrayDispatcherTrait}, | ||
erc20_felt252::{IERC20Felt252Dispatcher, IERC20Felt252DispatcherTrait}, | ||
}; | ||
use haiko_strategy_reversion::libraries::erc20_versioned_call; | ||
|
||
// External imports. | ||
use snforge_std::{declare, ContractClassTrait}; | ||
use openzeppelin::token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; | ||
|
||
#[test] | ||
fn test_erc20_bytearray() { | ||
let erc20_class = declare("ERC20ByteArray"); | ||
let name: ByteArray = "Mock"; | ||
let symbol: ByteArray = "MOCK"; | ||
let mut calldata = array![]; | ||
name.serialize(ref calldata); | ||
symbol.serialize(ref calldata); | ||
let contract_address = erc20_class.deploy(@calldata).unwrap(); | ||
let result = erc20_versioned_call::get_symbol(contract_address); | ||
println!("result(bytearray): {}", result); | ||
assert(result == "MOCK", 'Symbol (byte array)'); | ||
} | ||
|
||
#[test] | ||
fn test_erc20_felt252() { | ||
// Deploy erc20 | ||
let erc20_class = declare("ERC20Felt252"); | ||
let name: felt252 = 'Mock'; | ||
let symbol: felt252 = 'MOCK'; | ||
let mut calldata: Array<felt252> = array![]; | ||
name.serialize(ref calldata); | ||
symbol.serialize(ref calldata); | ||
let contract_address = erc20_class.deploy(@calldata).unwrap(); | ||
let result = erc20_versioned_call::get_symbol(contract_address); | ||
println!("result(felt252): {}", result); | ||
assert(result == "MOCK", 'Symbol (felt252)'); | ||
} |