Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
saimeunt committed Dec 9, 2024
1 parent 58ca354 commit 3221975
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 347 deletions.
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
scarb 2.9.1
22 changes: 17 additions & 5 deletions Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
[package]
name = "resolver"
version = "0.1.0"
edition = "2024_07"
cairo-version = "2.9.1"
scarb-version = "2.9.1"
authors = ["LFG Labs"]
description = "Resolver CCIP"
documentation = "https://github.com/lfglabs-dev/resolver_ccip"
readme = "README.md"
repository = "https://github.com/lfglabs-dev/resolver_ccip"

[dependencies]
starknet = "2.3.1"
naming = { git = "https://github.com/starknet-id/naming.git", rev = "6e45f7fc2bc9e8e9d874a1d2c2d46e3226a96f6d" }
openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", rev = "f3e2a5f0547a429c716f32471b06df729cbdfb9f" }
identity = { git = "https://github.com/starknet-id/identity.git", rev = "eb37846330b78e1410cf5e3e17a5dcca5652f921" }
storage_read = { git = "https://github.com/starknet-id/storage_read_component.git", rev = "c6c69e15d34abfc39ac51dc21b96724e2e19ff31" }
starknet = "2.9.1"
openzeppelin_access = "0.20.0"
openzeppelin_token = "0.20.0"
#naming = { git = "https://github.com/starknet-id/naming.git", rev = "7fa861a7a6e56c96ba3b508c66d7587d2597385a" }
#identity = { git = "https://github.com/starknet-id/identity.git", rev = "5ae7fafdd20abf4b1e789b83af5db7e23ad39a7c" }

[dev-dependencies]
cairo_test = "2.9.1"
openzeppelin_utils = "0.20.0"

[[target.starknet-contract]]
# Enable Sierra codegen.
Expand Down
2 changes: 1 addition & 1 deletion src/interface.cairo
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mod resolver;
pub mod resolver;
4 changes: 1 addition & 3 deletions src/interface/resolver.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use starknet::ContractAddress;

#[starknet::interface]
trait IResolver<TContractState> {
pub trait IResolver<TContractState> {
fn resolve(
self: @TContractState, domain: Span<felt252>, field: felt252, hint: Span<felt252>
) -> felt252;
Expand Down
100 changes: 33 additions & 67 deletions src/resolver.cairo
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
#[starknet::contract]
mod Resolver {
use core::option::OptionTrait;
use core::traits::TryInto;
use core::array::SpanTrait;
pub mod Resolver {
use core::hash::HashStateTrait;
use core::pedersen::PedersenTrait;
use core::ecdsa::check_ecdsa_signature;
use starknet::{ContractAddress, get_block_timestamp};
use ecdsa::check_ecdsa_signature;
use resolver::interface::resolver::{IResolver, IResolverDispatcher, IResolverDispatcherTrait};
use storage_read::{main::storage_read_component, interface::IStorageRead};
use openzeppelin::access::ownable::OwnableComponent;
use starknet::storage::{
Map, StoragePathEntry, StoragePointerReadAccess, StoragePointerWriteAccess
};
use openzeppelin_access::ownable::OwnableComponent;
use resolver::interface::resolver::IResolver;

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

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

#[storage]
struct Storage {
public_key: felt252,
uri: LegacyMap<(felt252, felt252), felt252>,
#[substorage(v0)]
storage_read: storage_read_component::Storage,
uris: Map<felt252, Map<felt252, felt252>>,
#[substorage(v0)]
ownable: OwnableComponent::Storage,
}
Expand All @@ -33,8 +29,6 @@ mod Resolver {
enum Event {
StarknetIDOffChainResolverUpdate: StarknetIDOffChainResolverUpdate,
#[flat]
StorageReadEvent: storage_read_component::Event,
#[flat]
OwnableEvent: OwnableComponent::Event,
}

Expand All @@ -44,14 +38,15 @@ mod Resolver {
uri_removed: Span<felt252>,
}

const REMOVED_URI_VALUE: felt252 = 'this call was removed';

#[constructor]
fn constructor(ref self: ContractState, owner: ContractAddress, _public_key: felt252) {
self.ownable.initializer(owner);
self.public_key.write(_public_key);
}

#[external(v0)]
#[abi(embed_v0)]
impl ResolverImpl of IResolver<ContractState> {
fn resolve(
self: @ContractState, domain: Span<felt252>, field: felt252, hint: Span<felt252>
Expand All @@ -64,15 +59,12 @@ mod Resolver {
assert(get_block_timestamp() < max_validity.try_into().unwrap(), 'Signature expired');

let hashed_domain = self.hash_domain(domain);
let message_hash: felt252 = hash::LegacyHash::hash(
hash::LegacyHash::hash(
hash::LegacyHash::hash(
hash::LegacyHash::hash('ccip_demo resolving', max_validity), hashed_domain
),
field
),
*hint.at(0)
);
let message_hash = PedersenTrait::new('ccip_demo resolving')
.update(max_validity)
.update(hashed_domain)
.update(field)
.update(*hint.at(0))
.finalize();

let public_key = self.public_key.read();
let is_valid = check_ecdsa_signature(
Expand All @@ -84,13 +76,13 @@ mod Resolver {
}

fn get_uris(self: @ContractState) -> Array<felt252> {
let mut res: Array<felt252> = array![];
let mut i: felt252 = 0;
let mut res = array![];
let mut i = 0;
loop {
if self.uri.read((i, 0)) == 0 {
if self.uris.entry(i).entry(0).read() == 0 {
break;
}
if self.uri.read((i, 0)) != 'this call was removed' {
if self.uris.entry(i).entry(0).read() != REMOVED_URI_VALUE {
// we get the next uri at index i
let mut new_uri = self.get_uri_at_index(i);
res.append(new_uri.len().into());
Expand All @@ -108,17 +100,10 @@ mod Resolver {

fn add_uri(ref self: ContractState, new_uri: Span<felt252>) {
self.ownable.assert_only_owner();
let mut i: felt252 = 0;
let mut i = 0;
loop {
if self.uri.read((i, 0)) == 0 {
self
.emit(
StarknetIDOffChainResolverUpdate {
uri_added: new_uri, uri_removed: array![].span()
}
);
if self.uris.entry(i).entry(0).read() == 0 {
self.store_uri(new_uri, i);

break;
}
i += 1;
Expand All @@ -129,17 +114,17 @@ mod Resolver {
self.ownable.assert_only_owner();
let uri_removed = self.get_uri_at_index(index).span();
self.emit(StarknetIDOffChainResolverUpdate { uri_added: array![].span(), uri_removed });
self.uri.write((index, 0), 'this call was removed');
self.uris.entry(index).entry(0).write(REMOVED_URI_VALUE);
}
}

#[generate_trait]
impl InternalImpl of InternalTrait {
pub impl InternalImpl of InternalTrait {
fn get_uri_at_index(self: @ContractState, index: felt252) -> Array<felt252> {
let mut res = array![];
let mut j: felt252 = 0;
let mut j = 0;
loop {
let value = self.uri.read((index, j));
let value = self.uris.entry(index).entry(j).read();
if value == 0 {
break;
}
Expand All @@ -154,7 +139,7 @@ mod Resolver {
loop {
match uri.pop_front() {
Option::Some(value) => {
self.uri.write((index, j), *value);
self.uris.entry(index).entry(j).write(*value);
j += 1;
},
Option::None => { break; }
Expand All @@ -174,27 +159,9 @@ mod Resolver {
}
};
// append uris to error array
self.append_uris(res)
}

fn append_uris(self: @ContractState, mut res: Array<felt252>) -> Array<felt252> {
let mut i: felt252 = 0;
loop {
if self.uri.read((i, 0)) == 0 {
break;
}
if self.uri.read((i, 0)) != 'this call was removed' {
// we get the next uri at index i
let mut new_uri = self.get_uri_at_index(i);
res.append(new_uri.len().into());
loop {
match new_uri.pop_front() {
Option::Some(value) => { res.append(value); },
Option::None => { break; }
}
};
}
i += 1;
let uris = self.get_uris();
for uri in uris {
res.append(uri);
};
res
}
Expand All @@ -206,8 +173,7 @@ mod Resolver {
let new_len = domain.len() - 1;
let x = *domain[new_len];
let y = self.hash_domain(domain.slice(0, new_len));
let hashed_domain = pedersen::pedersen(x, y);
return hashed_domain;
PedersenTrait::new(x).update(y).finalize()
}
}
}
29 changes: 14 additions & 15 deletions src/tests/resolver/erc20.cairo
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
#[starknet::contract]
mod ERC20 {
use openzeppelin::token::erc20::erc20::ERC20Component::InternalTrait;
use openzeppelin::{token::erc20::{ERC20Component, dual20::DualCaseERC20Impl}};
pub mod ERC20 {
use openzeppelin_token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
use starknet::ContractAddress;

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

// ERC20 Mixin
#[abi(embed_v0)]
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;
#[abi(embed_v0)]
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;

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

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

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

#[constructor]
fn constructor(ref self: ContractState, initial_supply: u256, recipient: ContractAddress) {
self.erc20.initializer("ether", "ETH");
self.erc20.mint(recipient, initial_supply);
}
}
6 changes: 0 additions & 6 deletions src/tests/resolver/test_hash.cairo
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
use array::ArrayTrait;
use debug::PrintTrait;

use starknet::ContractAddress;
use starknet::testing;
use resolver::interface::resolver::{IResolver, IResolverDispatcher, IResolverDispatcherTrait};
use resolver::resolver::Resolver;
use resolver::resolver::Resolver::InternalImpl;

Expand Down
Loading

0 comments on commit 3221975

Please sign in to comment.