Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: clean memecoin impl #105

Merged
merged 1 commit into from
Jan 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading