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

feat(interchain-token-service,interchain-token): add contract constructor #74

Merged
merged 11 commits into from
Nov 20, 2024
19 changes: 5 additions & 14 deletions contracts/interchain-token-service/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,15 @@ pub struct InterchainTokenService;

hydrobeam marked this conversation as resolved.
Show resolved Hide resolved
#[contractimpl]
impl InterchainTokenService {
pub fn initialize_its(env: Env, owner: Address) -> Result<(), ContractError> {
ensure!(
env.storage()
.instance()
.get::<DataKey, bool>(&DataKey::Initialized)
.is_none(),
ContractError::AlreadyInitialized
);

env.storage().instance().set(&DataKey::Initialized, &true);

pub fn __constructor(env: Env, owner: Address) {
env.storage().instance().set(&DataKey::Owner, &owner);

Ok(())
}

pub fn owner(env: &Env) -> Address {
env.storage().instance().get(&DataKey::Owner).unwrap()
env.storage()
.instance()
.get(&DataKey::Owner)
.expect("owner not found")
}

pub fn transfer_ownership(env: Env, new_owner: Address) {
Expand Down
8 changes: 3 additions & 5 deletions contracts/interchain-token-service/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use soroban_sdk::contracterror;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum ContractError {
NotInitialized = 1,
AlreadyInitialized = 2,
NotOwner = 3,
TrustedAddressAlreadySet = 4,
NoTrustedAddressSet = 5,
NotOwner = 1,
TrustedAddressAlreadySet = 2,
NoTrustedAddressSet = 3,
}
1 change: 0 additions & 1 deletion contracts/interchain-token-service/src/storage_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use soroban_sdk::{contracttype, String};
#[contracttype]
#[derive(Clone, Debug)]
pub enum DataKey {
Initialized,
Owner,
TrustedAddress(String),
}
87 changes: 24 additions & 63 deletions contracts/interchain-token-service/src/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,38 @@ use soroban_sdk::testutils::{MockAuth, MockAuthInvoke};

use soroban_sdk::{testutils::Address as _, Address, Env, String, Symbol};

fn setup_env<'a>() -> (Env, Address, InterchainTokenServiceClient<'a>) {
fn setup_env<'a>() -> (Env, InterchainTokenServiceClient<'a>) {
let env = Env::default();

let contract_id = env.register_contract(None, InterchainTokenService);
let owner = Address::generate(&env);
let contract_id = env.register(InterchainTokenService, (&owner,));
let client = InterchainTokenServiceClient::new(&env, &contract_id);

(env, contract_id, client)
}

fn initialize(_env: &Env, client: &InterchainTokenServiceClient, owner: Address) {
client.initialize_its(&owner);
(env, client)
}

#[test]
fn initialize_succeeds() {
let (env, _, client) = setup_env();
fn register_interchain_token_service() {
let env = Env::default();
let owner = Address::generate(&env);

initialize(&env, &client, owner.clone());
let contract_id = env.register(InterchainTokenService, (&owner,));
let client = InterchainTokenServiceClient::new(&env, &contract_id);

assert_eq!(client.owner(), owner);
}

#[test]
fn initialize_fails_if_already_initialized() {
let (env, _, client) = setup_env();
let owner = Address::generate(&env);

initialize(&env, &client, owner.clone());

assert_contract_err!(
client.try_initialize_its(&owner),
ContractError::AlreadyInitialized
);
}

#[test]
fn set_trusted_address() {
let (env, contract_id, client) = setup_env();
let owner = Address::generate(&env);

initialize(&env, &client, owner);
let (env, client) = setup_env();
env.mock_all_auths();

let chain = String::from_str(&env, "chain");
let trusted_address = String::from_str(&env, "trusted_address");

env.mock_all_auths();

client.set_trusted_address(&chain, &trusted_address);

assert_last_emitted_event(
&env,
&contract_id,
&client.address,
(
Symbol::new(&env, "trusted_address_set"),
chain.clone(),
Expand All @@ -72,10 +51,7 @@ fn set_trusted_address() {

#[test]
fn set_trusted_address_fails_if_not_owner() {
let (env, _, client) = setup_env();
let owner = Address::generate(&env);

initialize(&env, &client, owner);
let (env, client) = setup_env();

let not_owner = Address::generate(&env);
let chain = String::from_str(&env, "chain");
Expand All @@ -89,17 +65,13 @@ fn set_trusted_address_fails_if_not_owner() {

#[test]
fn set_trusted_address_fails_if_already_set() {
let (env, _, client) = setup_env();
let owner = Address::generate(&env);

initialize(&env, &client, owner);
let (env, client) = setup_env();
env.mock_all_auths();

let chain = String::from_str(&env, "chain");
let trusted_address = String::from_str(&env, "trusted_address");
let another_trusted_address = String::from_str(&env, "another_trusted_address");

env.mock_all_auths();

client.set_trusted_address(&chain, &trusted_address);

assert_contract_err!(
Expand All @@ -114,23 +86,19 @@ fn set_trusted_address_fails_if_already_set() {

#[test]
fn remove_trusted_address() {
let (env, contract_id, client) = setup_env();
let owner = Address::generate(&env);

initialize(&env, &client, owner);
let (env, client) = setup_env();
env.mock_all_auths();

let chain = String::from_str(&env, "chain");
let trusted_address = String::from_str(&env, "trusted_address");

env.mock_all_auths();

client.set_trusted_address(&chain, &trusted_address);

client.remove_trusted_address(&chain);

assert_last_emitted_event(
&env,
&contract_id,
&client.address,
(
Symbol::new(&env, "trusted_address_removed"),
chain.clone(),
Expand All @@ -144,17 +112,13 @@ fn remove_trusted_address() {

#[test]
fn remove_trusted_address_fails_if_address_not_set() {
let (env, _, client) = setup_env();
let owner = Address::generate(&env);

initialize(&env, &client, owner);
let (env, client) = setup_env();
env.mock_all_auths();

let chain = String::from_str(&env, "chain");

assert_eq!(client.trusted_address(&chain), None);

env.mock_all_auths();

assert_contract_err!(
client.try_remove_trusted_address(&chain),
ContractError::NoTrustedAddressSet
Expand All @@ -163,23 +127,20 @@ fn remove_trusted_address_fails_if_address_not_set() {

#[test]
fn transfer_ownership() {
let (env, contract_id, client) = setup_env();
let owner = Address::generate(&env);

initialize(&env, &client, owner.clone());
let (env, client) = setup_env();
env.mock_all_auths();

let prev_owner = client.owner();
let new_owner = Address::generate(&env);

env.mock_all_auths();

client.transfer_ownership(&new_owner);

assert_last_emitted_event(
&env,
&contract_id,
&client.address,
(
Symbol::new(&env, "ownership_transferred"),
owner,
prev_owner,
new_owner.clone(),
),
(),
Expand Down
26 changes: 5 additions & 21 deletions contracts/interchain-token/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use axelar_soroban_std::ensure;
use soroban_sdk::{contract, contractimpl, Address, Env};

use crate::error::ContractError;
use crate::event;
use crate::storage_types::DataKey;

Expand All @@ -10,37 +8,23 @@ pub struct InterchainToken;

#[contractimpl]
impl InterchainToken {
pub fn initialize(env: Env, owner: Address) -> Result<(), ContractError> {
ensure!(
env.storage()
.instance()
.get::<DataKey, bool>(&DataKey::Initialized)
.is_none(),
ContractError::AlreadyInitialized
);

env.storage().instance().set(&DataKey::Initialized, &true);

pub fn __constructor(env: Env, owner: Address) {
env.storage().instance().set(&DataKey::Owner, &owner);

Ok(())
}

pub fn owner(env: &Env) -> Result<Address, ContractError> {
pub fn owner(env: &Env) -> Address {
env.storage()
.instance()
.get(&DataKey::Owner)
.ok_or(ContractError::NotInitialized)
.expect("owner not found")
}

pub fn transfer_ownership(env: Env, new_owner: Address) -> Result<(), ContractError> {
let owner: Address = Self::owner(&env)?;
pub fn transfer_ownership(env: Env, new_owner: Address) {
let owner: Address = Self::owner(&env);
owner.require_auth();

env.storage().instance().set(&DataKey::Owner, &new_owner);

event::transfer_ownership(&env, owner, new_owner);

Ok(())
}
}
9 changes: 0 additions & 9 deletions contracts/interchain-token/src/error.rs

This file was deleted.

1 change: 0 additions & 1 deletion contracts/interchain-token/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![no_std]

pub mod error;
mod event;
mod storage_types;

Expand Down
1 change: 0 additions & 1 deletion contracts/interchain-token/src/storage_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ use soroban_sdk::contracttype;
#[contracttype]
#[derive(Clone, Debug)]
pub enum DataKey {
Initialized,
Owner,
}
54 changes: 13 additions & 41 deletions contracts/interchain-token/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,43 @@
extern crate std;

use axelar_soroban_std::{
assert_contract_err, assert_invoke_auth_err, assert_invoke_auth_ok, assert_last_emitted_event,
assert_invoke_auth_err, assert_invoke_auth_ok, assert_last_emitted_event,
};
use interchain_token::contract::InterchainToken;
use interchain_token::error::ContractError;
use interchain_token::InterchainTokenClient;
use soroban_sdk::testutils::{Address as _, MockAuth, MockAuthInvoke};
use soroban_sdk::{Address, Env, IntoVal, Symbol};

fn setup_env<'a>() -> (Env, Address, InterchainTokenClient<'a>) {
fn setup_env<'a>() -> (Env, InterchainTokenClient<'a>) {
let env = Env::default();

let contract_id = env.register_contract(None, InterchainToken);
let owner = Address::generate(&env);
let contract_id = env.register(InterchainToken, (&owner,));
let client = InterchainTokenClient::new(&env, &contract_id);

(env, contract_id, client)
}

fn initialize(_env: &Env, client: &InterchainTokenClient, owner: Address) {
client.initialize(&owner);
(env, client)
}

#[test]
fn initialize_succeeds() {
let (env, _, client) = setup_env();
fn register_interchain_token() {
let env = Env::default();
let owner = Address::generate(&env);

initialize(&env, &client, owner.clone());
let contract_id = env.register(InterchainToken, (&owner,));
let client = InterchainTokenClient::new(&env, &contract_id);

assert_eq!(client.owner(), owner);
}

#[test]
fn initialize_fails_if_already_initialized() {
let (env, _, client) = setup_env();
let owner = Address::generate(&env);

initialize(&env, &client, owner.clone());

assert_contract_err!(
client.try_initialize(&owner),
ContractError::AlreadyInitialized
);
}

#[test]
fn transfer_ownership() {
let (env, contract_id, client) = setup_env();
let owner = Address::generate(&env);
let (env, client) = setup_env();
let owner = client.owner();
let new_owner = Address::generate(&env);

initialize(&env, &client, owner.clone());

assert_eq!(client.owner(), owner);

assert_invoke_auth_ok!(owner, client.try_transfer_ownership(&new_owner));

assert_last_emitted_event(
&env,
&contract_id,
&client.address,
(
Symbol::new(&env, "ownership_transferred"),
owner,
Expand All @@ -74,13 +52,7 @@ fn transfer_ownership() {

#[test]
fn transfer_ownership_unauthorized() {
let (env, _, client) = setup_env();
let owner = Address::generate(&env);
let (env, client) = setup_env();
let new_owner = Address::generate(&env);

initialize(&env, &client, owner.clone());

assert_eq!(client.owner(), owner);

assert_invoke_auth_err!(new_owner, client.try_transfer_ownership(&new_owner));
}
Loading