Skip to content

Commit

Permalink
refactor: clean memecoin impl
Browse files Browse the repository at this point in the history
feat: make transfer_limit_delay a parameter
feat: PercentageMath library
  • Loading branch information
enitrat committed Dec 29, 2023
1 parent 659f01f commit 7564aea
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 465 deletions.
60 changes: 14 additions & 46 deletions contracts/src/factory/factory.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ mod Factory {
}

#[abi(embed_v0)]
impl UnruggableMemeCoinFactoryImpl of IFactory<ContractState> {
impl FactoryImpl of IFactory<ContractState> {
fn create_memecoin(
ref self: ContractState,
owner: ContractAddress,
Expand All @@ -84,13 +84,18 @@ mod Factory {
initial_supply: u256,
initial_holders: Span<ContractAddress>,
initial_holders_amounts: Span<u256>,
eth_contract: ERC20ABIDispatcher,
contract_address_salt: felt252
transfer_limit_delay: u64,
counterparty_token: ERC20ABIDispatcher,
contract_address_salt: felt252,
) -> ContractAddress {
// General calldata
let mut calldata = serialize_calldata(
owner, locker_address, name, symbol, initial_supply
);
let mut calldata = array![
owner.into(),
locker_address.into(),
transfer_limit_delay.into(),
name.into(),
symbol.into()
];
Serde::serialize(@initial_supply, ref calldata);
Serde::serialize(@initial_holders.into(), ref calldata);
Serde::serialize(@initial_holders_amounts.into(), ref calldata);

Expand All @@ -105,18 +110,9 @@ mod Factory {
let caller = get_caller_address();
//TODO(make the initial liquidity a parameter)
let eth_amount: u256 = 1 * ETH_UNIT_DECIMALS;
assert(
eth_contract.allowance(caller, get_contract_address()) == eth_amount,
'ETH allowance not enough'
);
eth_contract
.transferFrom(sender: caller, recipient: memecoin_address, amount: eth_amount);

//TODO(audit): why does it matter if the coin has _more_ than 1 ETH?
assert(
eth_contract.balanceOf(memecoin_address) == eth_amount, 'memecoin should have 1ETH'
);

counterparty_token
.transferFrom(sender: caller, recipient: memecoin_address, amount: eth_amount);
self.emit(MemeCoinCreated { owner, name, symbol, initial_supply, memecoin_address });

memecoin_address
Expand All @@ -130,32 +126,4 @@ mod Factory {
self.deployed_memecoins.read(address)
}
}

/// Serializes input parameters into calldata.
///
/// # Arguments
///
/// * `owner` - The address of the contract owner.
/// * `locker_address` - The address of the locker contract associated with the contract.
/// * `name` - The name of the contract.
/// * `symbol` - The symbol of the contract.
/// * `initial_supply` - The initial supply of the contract.
///
/// # Returns
///
/// An array containing the serialized calldata.
fn serialize_calldata(
owner: ContractAddress,
locker_address: ContractAddress,
name: felt252,
symbol: felt252,
initial_supply: u256
) -> Array<felt252> {
//TODO(fix): serialize_calldata shouldn't have a hardcoded value here. - or at least, it should be named.
let mut calldata = array![
owner.into(), locker_address.into(), 1000.into(), name.into(), symbol.into()
]; // Third param should be lock delay.
Serde::serialize(@initial_supply, ref calldata);
calldata
}
}
7 changes: 5 additions & 2 deletions contracts/src/factory/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use starknet::ContractAddress;

#[starknet::interface]
trait IFactory<TContractState> {
/// Creates a new memecoin.
/// Deploys a new memecoin, using the class hash that was registered in the factory upon initialization.
///
/// This function deploys a new memecoin contract with the given parameters,
/// transfers 1 ETH from the caller to the new memecoin, and emits a `MemeCoinCreated` event.
Expand All @@ -15,6 +15,8 @@ trait IFactory<TContractState> {
/// * `initial_supply` - The initial supply of the Memecoin.
/// * `initial_holders` - An array containing the initial holders' addresses.
/// * `initial_holders_amounts` - An array containing the initial amounts held by each corresponding initial holder.
/// * `transfer_limit_delay` - The delay in seconds during which transfers will be limited to a % of max supply after launch.
/// * `counterparty_token` - The address of the counterparty token
/// * `contract_address_salt` - A unique salt value for contract deployment
///
/// # Returns
Expand All @@ -29,7 +31,8 @@ trait IFactory<TContractState> {
initial_supply: u256,
initial_holders: Span<ContractAddress>,
initial_holders_amounts: Span<u256>,
eth_contract: ERC20ABIDispatcher,
transfer_limit_delay: u64,
counterparty_token: ERC20ABIDispatcher,
contract_address_salt: felt252
) -> ContractAddress;

Expand Down
4 changes: 4 additions & 0 deletions contracts/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ mod locker;
mod tests;
mod tokens;

mod utils {
mod math;
}

mod mocks {
mod erc20;
mod jediswap {
Expand Down
1 change: 0 additions & 1 deletion contracts/src/locker/token_locker.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//TODO(low prio): implement fallback mechanism for snake_case entrypoints
//TODO(low prio): implement a recover functions for tokens wrongly sent to the contract
//TODO(high prio): keep a list of all active locks per users.
#[starknet::contract]
mod TokenLocker {
use alexandria_storage::list::{List, ListTrait};
Expand Down
15 changes: 9 additions & 6 deletions contracts/src/tests/test_factory.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use unruggable::amm::amm::{AMM, AMMV2, AMMTrait};
use unruggable::factory::{IFactory, IFactoryDispatcher, IFactoryDispatcherTrait};
use unruggable::tests::utils::{
deploy_amm_factory_and_router, deploy_meme_factory, deploy_locker, deploy_eth, OWNER, NAME,
SYMBOL, ETH_INITIAL_SUPPLY, INITIAL_HOLDERS, INITIAL_HOLDERS_AMOUNTS, SALT
SYMBOL, DEFAULT_INITIAL_SUPPLY, INITIAL_HOLDERS, INITIAL_HOLDERS_AMOUNTS, SALT
};
use unruggable::tokens::interface::{
IUnruggableMemecoin, IUnruggableMemecoinDispatcher, IUnruggableMemecoinDispatcherTrait
Expand Down Expand Up @@ -44,10 +44,11 @@ fn test_is_memecoin() {
:locker_address,
name: NAME(),
symbol: SYMBOL(),
initial_supply: ETH_INITIAL_SUPPLY(),
initial_supply: DEFAULT_INITIAL_SUPPLY(),
initial_holders: INITIAL_HOLDERS(),
initial_holders_amounts: INITIAL_HOLDERS_AMOUNTS(),
eth_contract: eth,
transfer_limit_delay: 1000,
counterparty_token: eth,
contract_address_salt: SALT(),
);
stop_prank(CheatTarget::One(memecoin_factory.contract_address));
Expand Down Expand Up @@ -82,10 +83,11 @@ fn test_create_memecoin() {
:locker_address,
name: NAME(),
symbol: SYMBOL(),
initial_supply: ETH_INITIAL_SUPPLY(),
initial_supply: DEFAULT_INITIAL_SUPPLY(),
initial_holders: INITIAL_HOLDERS(),
initial_holders_amounts: INITIAL_HOLDERS_AMOUNTS(),
eth_contract: eth,
transfer_limit_delay: 1000,
counterparty_token: eth,
contract_address_salt: SALT(),
);
stop_prank(CheatTarget::One(memecoin_factory.contract_address));
Expand All @@ -96,7 +98,8 @@ fn test_create_memecoin() {
assert(memecoin.symbol() == SYMBOL(), 'wrong memecoin symbol');
// initial supply - initial holder balance
assert(
memecoin.balanceOf(memecoin_address) == ETH_INITIAL_SUPPLY() - 100, 'wrong initial supply'
memecoin.balanceOf(memecoin_address) == DEFAULT_INITIAL_SUPPLY() - 100,
'wrong initial supply'
);
assert(memecoin.balanceOf(*INITIAL_HOLDERS()[0]) == 50, 'wrong initial_holder_1 balance');
assert(memecoin.balanceOf(*INITIAL_HOLDERS()[1]) == 50, 'wrong initial_holder_2 balance');
Expand Down
2 changes: 2 additions & 0 deletions contracts/src/tests/test_token_locker.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use unruggable::tokens::interface::{
const DEFAULT_LOCK_DEADLINE: u64 = 300;
const DEFAULT_LOCK_AMOUNT: u256 = 100;

/// Sets up the locker contract and deploys a token contract.
/// For simplicity, the token deployed is the default "ETH" token.
fn setup() -> (ERC20ABIDispatcher, ITokenLockerDispatcher) {
let (token, token_address) = deploy_eth();
let locker = deploy_locker();
Expand Down
Loading

0 comments on commit 7564aea

Please sign in to comment.