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

Bring fixes #62

Merged
merged 23 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e9c80c8
fix: unused imports
irisdv May 17, 2024
109f9cc
fix: remove unused metadata argument in set_expiry
irisdv May 17, 2024
a764a4d
fix: user could buy empty domain
irisdv May 21, 2024
e6d9997
fix: check retrun values of ERC20 transfer & transferFrom functions
irisdv May 21, 2024
5b3ce9e
fix: return hashed_domain if resolver returns 0
irisdv May 27, 2024
aef5a63
fix: remove unecessary space
irisdv May 27, 2024
870dd63
Merge pull request #51 from starknet-id/fix/unused_imports
Th0rgal May 28, 2024
ae4f0f9
Merge pull request #52 from starknet-id/fix/unused_variable_in_set_ex…
Th0rgal May 28, 2024
052aabe
Merge pull request #53 from starknet-id/fix/user_could_buy_empty_domain
Th0rgal May 28, 2024
a62d868
Merge pull request #55 from starknet-id/fix/returning0_as_hashed_domain
Th0rgal May 28, 2024
f8fe076
Merge branch 'master' into fix/unchecked_return_erc20
Th0rgal May 28, 2024
86c0820
fix: domain can't be empty typo
Th0rgal May 28, 2024
2eadb70
Merge pull request #54 from starknet-id/fix/unchecked_return_erc20
Th0rgal May 28, 2024
e21dda5
feat: add config for voyager verification
Th0rgal May 30, 2024
309e39d
feat: update admin
irisdv Jun 5, 2024
fcccbb2
feat: remove update_admin and finalize upgrade
irisdv Jun 5, 2024
a72c078
fix: write admin_address to 0 and update is_admin checks
irisdv Jun 5, 2024
9197a69
fix: rebase with part 1 & remove unused storage var
irisdv Jun 5, 2024
f440c3b
Merge pull request #56 from starknet-id/feat/add_accept_admin
Th0rgal Jun 5, 2024
c0f19ac
ref: update add erc20 addr in add_commission
irisdv Jun 10, 2024
25ecd41
Merge pull request #57 from starknet-id/feat/add_accept_admin2
Th0rgal Jun 10, 2024
6993eee
Merge pull request #58 from starknet-id/feat/add_commission_altcoins
Th0rgal Jun 10, 2024
7e8dc83
Merge branch 'fix/test_use_reset_subdomains_multiple_levels' into fea…
Th0rgal Jun 11, 2024
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
3 changes: 3 additions & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ casm-add-pythonic-hints = true

build-external-contracts = ["identity::identity::main::Identity"]

[tool.voyager]
naming = { path = "src/naming.cairo" }

[lib]
sierra = true
casm = false
4 changes: 1 addition & 3 deletions src/interface/naming.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,8 @@ trait INaming<TContractState> {
);

// admin
fn set_admin(ref self: TContractState, new_admin: ContractAddress);

fn set_expiry(ref self: TContractState, root_domain: felt252, expiry: u64, metadata: felt252);
fn set_expiry(ref self: TContractState, root_domain: felt252, expiry: u64);

fn claim_balance(ref self: TContractState, erc20: ContractAddress);

Expand All @@ -123,5 +122,4 @@ trait INaming<TContractState> {
fn blacklist_renewal_contract(ref self: TContractState, contract: ContractAddress);

fn toggle_ar_discount_renew(ref self: TContractState);

}
3 changes: 2 additions & 1 deletion src/interface/referral.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ trait IReferral<TContractState> {
self: @TContractState,
amount: u256,
sponsor_addr: ContractAddress,
sponsored_addr: ContractAddress
sponsored_addr: ContractAddress,
erc20_addr: ContractAddress,
);
}
2 changes: 0 additions & 2 deletions src/interface/resolver.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use starknet::ContractAddress;

#[starknet::interface]
trait IResolver<TContractState> {
fn resolve(
Expand Down
7 changes: 0 additions & 7 deletions src/naming/asserts.cairo
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
use core::traits::TryInto;
use core::array::SpanTrait;
use naming::{
interface::{
naming::{INaming, INamingDispatcher, INamingDispatcherTrait},
resolver::{IResolver, IResolverDispatcher, IResolverDispatcherTrait},
pricing::{IPricing, IPricingDispatcher, IPricingDispatcherTrait},
referral::{IReferral, IReferralDispatcher, IReferralDispatcherTrait},
},
naming::main::{
Naming,
Naming::{
Expand All @@ -25,7 +19,6 @@ use starknet::{
use openzeppelin::token::erc20::interface::{
IERC20Camel, IERC20CamelDispatcher, IERC20CamelDispatcherTrait
};
use integer::{u256_safe_divmod, u256_as_non_zero};
use naming::naming::utils::UtilsTrait;

#[generate_trait]
Expand Down
21 changes: 11 additions & 10 deletions src/naming/internal.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use naming::{
interface::{
naming::{INaming, INamingDispatcher, INamingDispatcherTrait},
resolver::{IResolver, IResolverDispatcher, IResolverDispatcherTrait},
pricing::{IPricing, IPricingDispatcher, IPricingDispatcherTrait},
referral::{IReferral, IReferralDispatcher, IReferralDispatcherTrait},
},
naming::main::{
Expand All @@ -18,7 +16,7 @@ use naming::{
use identity::interface::identity::{IIdentity, IIdentityDispatcher, IIdentityDispatcherTrait};
use starknet::{
contract_address::ContractAddressZeroable, ContractAddress, get_caller_address,
get_contract_address, get_block_timestamp
get_contract_address
};
use openzeppelin::token::erc20::interface::{
IERC20Camel, IERC20CamelDispatcher, IERC20CamelDispatcherTrait
Expand Down Expand Up @@ -102,12 +100,13 @@ impl InternalImpl of InternalTrait {
};

// pay the price
IERC20CamelDispatcher { contract_address: erc20 }
let has_payed = IERC20CamelDispatcher { contract_address: erc20 }
.transferFrom(get_caller_address(), get_contract_address(), discounted_price);
assert(has_payed, 'payment failed');
// add sponsor commission if eligible
if sponsor.into() != 0 {
IReferralDispatcher { contract_address: self._referral_contract.read() }
.add_commission(discounted_price, sponsor, sponsored_addr: get_caller_address());
.add_commission(discounted_price, sponsor, sponsored_addr: get_caller_address(), erc20_addr: erc20);
}
}

Expand Down Expand Up @@ -149,11 +148,13 @@ impl InternalImpl of InternalTrait {
) -> (felt252, felt252) {
let (resolver, parent_start) = self.domain_to_resolver(domain, 1);
if (resolver != ContractAddressZeroable::zero()) {
(
0,
IResolverDispatcher { contract_address: resolver }
.resolve(domain.slice(0, parent_start), field, hint)
)
let resolver_res = IResolverDispatcher { contract_address: resolver }
.resolve(domain.slice(0, parent_start), field, hint);
if resolver_res == 0 {
let hashed_domain = self.hash_domain(domain);
return (0, hashed_domain);
}
return (0, resolver_res);
} else {
let hashed_domain = self.hash_domain(domain);
let domain_data = self._domain_data.read(hashed_domain);
Expand Down
55 changes: 28 additions & 27 deletions src/naming/main.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ mod Naming {
use array::{ArrayTrait, SpanTrait};
use zeroable::Zeroable;
use starknet::class_hash::ClassHash;
use integer::{u256_safe_divmod, u256_as_non_zero};
use core::pedersen;
use hash::LegacyHash;
use ecdsa::check_ecdsa_signature;
Expand All @@ -17,17 +16,14 @@ mod Naming {
naming::{asserts::AssertionsTrait, internal::InternalTrait, utils::UtilsTrait},
interface::{
naming::{INaming, INamingDispatcher, INamingDispatcherTrait},
resolver::{IResolver, IResolverDispatcher, IResolverDispatcherTrait},
pricing::{IPricing, IPricingDispatcher, IPricingDispatcherTrait},
referral::{IReferral, IReferralDispatcher, IReferralDispatcherTrait},
auto_renewal::{IAutoRenewal, IAutoRenewalDispatcher, IAutoRenewalDispatcherTrait}
}
};
use clone::Clone;
use array::ArrayTCloneImpl;
use identity::interface::identity::{IIdentity, IIdentityDispatcher, IIdentityDispatcherTrait};
use openzeppelin::token::erc20::interface::{
IERC20Camel, IERC20CamelDispatcher, IERC20CamelDispatcherTrait
use openzeppelin::{
access::ownable::OwnableComponent,
token::erc20::interface::{IERC20Camel, IERC20CamelDispatcher, IERC20CamelDispatcherTrait}
};
use storage_read::{main::storage_read_component, interface::IStorageRead};

Expand All @@ -43,7 +39,9 @@ mod Naming {
DomainMigrated: DomainMigrated,
SubdomainsReset: SubdomainsReset,
SaleMetadata: SaleMetadata,
StorageReadEvent: storage_read_component::Event
StorageReadEvent: storage_read_component::Event,
#[flat]
OwnableEvent: OwnableComponent::Event,
}

#[derive(Drop, starknet::Event)]
Expand Down Expand Up @@ -131,7 +129,6 @@ mod Naming {
starknetid_contract: ContractAddress,
_pricing_contract: ContractAddress,
_referral_contract: ContractAddress,
_admin_address: ContractAddress,
_domain_data: LegacyMap<felt252, DomainData>,
_hash_to_domain: LegacyMap<(felt252, usize), felt252>,
_address_to_domain: LegacyMap<(ContractAddress, usize), felt252>,
Expand All @@ -142,6 +139,8 @@ mod Naming {
_ar_discount_renew_enabled: bool,
#[substorage(v0)]
storage_read: storage_read_component::Storage,
#[substorage(v0)]
ownable: OwnableComponent::Storage,
}

#[constructor]
Expand All @@ -155,13 +154,17 @@ mod Naming {
self.starknetid_contract.write(starknetid);
self._pricing_contract.write(pricing);
self._referral_contract.write(referral);
self._admin_address.write(admin);
self.ownable.initializer(admin);
}

component!(path: storage_read_component, storage: storage_read, event: StorageReadEvent);
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);

#[abi(embed_v0)]
impl StorageReadComponent = storage_read_component::StorageRead<ContractState>;
#[abi(embed_v0)]
impl OwnableTwoStepImpl = OwnableComponent::OwnableTwoStepImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;

#[abi(embed_v0)]
impl NamingImpl of INaming<ContractState> {
Expand Down Expand Up @@ -284,6 +287,7 @@ mod Naming {
let (hashed_domain, now, expiry) = self.assert_purchase_is_possible(id, domain, days);
// we need a u256 to be able to perform safe divisions
let domain_len = self.get_chars_len(domain.into());
assert(domain_len != 0, 'domain can\'t be empty');
// find domain cost
let (erc20, price) = IPricingDispatcher {
contract_address: self._pricing_contract.read()
Expand Down Expand Up @@ -311,6 +315,7 @@ mod Naming {
let (hashed_domain, now, expiry) = self.assert_purchase_is_possible(id, domain, days);
// we need a u256 to be able to perform safe divisions
let domain_len = self.get_chars_len(domain.into());
assert(domain_len != 0, 'domain can\'t be empty');

// check quote timestamp is still valid
assert(get_block_timestamp() <= max_validity, 'quotation expired');
Expand Down Expand Up @@ -702,15 +707,10 @@ mod Naming {

// ADMIN

fn set_admin(ref self: ContractState, new_admin: ContractAddress) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self._admin_address.write(new_admin);
}

fn set_expiry(
ref self: ContractState, root_domain: felt252, expiry: u64, metadata: felt252
ref self: ContractState, root_domain: felt252, expiry: u64
) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
let hashed_domain = self.hash_domain(array![root_domain].span());
let domain_data = self._domain_data.read(hashed_domain);
let data = DomainData {
Expand All @@ -729,53 +729,54 @@ mod Naming {
}

fn claim_balance(ref self: ContractState, erc20: ContractAddress) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
let balance = IERC20CamelDispatcher { contract_address: erc20 }
.balanceOf(get_contract_address());
IERC20CamelDispatcher { contract_address: erc20 }
let has_claimed = IERC20CamelDispatcher { contract_address: erc20 }
.transfer(get_caller_address(), balance);
assert(has_claimed, 'Claim failed');
}

fn set_discount(ref self: ContractState, discount_id: felt252, discount: Discount) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
self.discounts.write(discount_id, discount);
}

fn set_pricing_contract(ref self: ContractState, pricing_contract: ContractAddress) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
self._pricing_contract.write(pricing_contract);
}

fn set_referral_contract(ref self: ContractState, referral_contract: ContractAddress) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
self._referral_contract.write(referral_contract);
}

fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
// todo: use components
assert(!new_class_hash.is_zero(), 'Class hash cannot be zero');
starknet::replace_class_syscall(new_class_hash).unwrap();
}

fn set_server_pub_key(ref self: ContractState, new_key: felt252) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
self._server_pub_key.write(new_key);
}

fn whitelist_renewal_contract(ref self: ContractState, contract: ContractAddress) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
self._whitelisted_renewal_contracts.write(contract, true);
}

fn blacklist_renewal_contract(ref self: ContractState, contract: ContractAddress) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
self._whitelisted_renewal_contracts.write(contract, false);
}


fn toggle_ar_discount_renew(ref self: ContractState) {
assert(get_caller_address() == self._admin_address.read(), 'you are not admin');
self.ownable.assert_only_owner();
self._ar_discount_renew_enabled.write(!self._ar_discount_renew_enabled.read());
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/naming/utils.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::array::SpanTrait;
use naming::{naming::main::{Naming, Naming::_hash_to_domainContractMemberStateTrait}};
use integer::{u256_safe_divmod, u256_as_non_zero};
use wadray::{Wad, WAD_SCALE};
use wadray::Wad;

#[generate_trait]
impl UtilsImpl of UtilsTrait {
Expand Down
1 change: 1 addition & 0 deletions src/tests/naming.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ mod test_usecases;
mod test_features;
mod test_altcoin;
mod test_ar_discount;
mod test_admin_update;
71 changes: 71 additions & 0 deletions src/tests/naming/common.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,74 @@ fn deploy_stark() -> IERC20CamelDispatcher {
let stark = utils::deploy(ERC20::TEST_CLASS_HASH, array![]);
IERC20CamelDispatcher { contract_address: stark }
}

fn deploy_with_erc20_fail() -> (IERC20CamelDispatcher, IPricingDispatcher, IIdentityDispatcher, INamingDispatcher) {
//erc20
let eth = utils::deploy(ERC20Fail::TEST_CLASS_HASH, array![]);

// pricing
let pricing = utils::deploy(Pricing::TEST_CLASS_HASH, array![eth.into()]);

// identity
let identity = utils::deploy(Identity::TEST_CLASS_HASH, array![0x123, 0, 0, 0]);

// naming
let admin = 0x123;
let address = utils::deploy(
Naming::TEST_CLASS_HASH, array![identity.into(), pricing.into(), 0, admin]
);

(
IERC20CamelDispatcher { contract_address: eth },
IPricingDispatcher { contract_address: pricing },
IIdentityDispatcher { contract_address: identity },
INamingDispatcher { contract_address: address }
)
}

#[starknet::contract]
mod ERC20Fail {
use starknet::ContractAddress;
use openzeppelin::token::erc20::erc20::ERC20Component::InternalTrait as ERC20InternalTrait;
use openzeppelin::{
token::erc20::{ERC20Component, dual20::DualCaseERC20Impl, ERC20HooksEmptyImpl}
};

component!(path: ERC20Component, storage: erc20, event: ERC20Event);

#[abi(embed_v0)]
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;

#[constructor]
fn constructor(ref self: ContractState) {
self.erc20.initializer("ether", "ETH");
let target = starknet::contract_address_const::<0x123>();
self.erc20._mint(target, 0x100000000000000000000000000000000);
}

#[storage]
struct Storage {
#[substorage(v0)]
erc20: ERC20Component::Storage,
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
ERC20Event: ERC20Component::Event,
}

#[abi(per_item)]
#[generate_trait]
impl ExternalImpl of ExternalTrait {
#[external(v0)]
fn transferFrom(
ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256
) -> bool {
false
}
}
}
Loading
Loading