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

Synchronize the API with Omni Token. #252

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
54 changes: 37 additions & 17 deletions bridge-token-factory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ const SET_METADATA_GAS: Gas = Gas(Gas::ONE_TERA.0 * 5);
/// Amount of gas used by bridge token to pause withdraw.
const SET_PAUSED_GAS: Gas = Gas(Gas::ONE_TERA.0 * 5);

// Amount of gas used by bridge token to set new controller
const SET_CONTROLLER_GAS: Gas = Gas(Gas::ONE_TERA.0 * 5);

/// Amount of gas used by `upgrade_bridge_token` in the factory, without taking into account
/// the gas consumed by the promise.
const OUTER_UPGRADE_TOKEN_GAS: Gas = Gas(Gas::ONE_TERA.0 * 15);
Expand Down Expand Up @@ -155,7 +158,12 @@ pub trait ExtBridgeTokenFactory {

#[ext_contract(ext_bridge_token)]
pub trait ExtBridgeToken {
fn mint(&self, account_id: AccountId, amount: U128);
fn mint(
&self,
account_id: AccountId,
amount: U128,
msg: Option<String>,
) -> PromiseOrValue<U128>;

fn ft_transfer_call(
&mut self,
Expand All @@ -178,6 +186,8 @@ pub trait ExtBridgeToken {
fn set_paused(&mut self, paused: bool);

fn attach_full_access_key(&mut self, public_key: PublicKey) -> Promise;

fn set_new_controller(&mut self, new_controller: Option<AccountId>);
}

pub fn assert_self() {
Expand Down Expand Up @@ -399,31 +409,21 @@ impl BridgeTokenFactory {
target, message
));

match message {
Some(message) => ext_bridge_token::ext(self.get_bridge_token_account_id(token.clone()))
.with_static_gas(MINT_GAS)
.with_attached_deposit(env::attached_deposit() - required_deposit)
.mint(env::current_account_id(), amount.into())
.then(
ext_bridge_token::ext(self.get_bridge_token_account_id(token))
.with_static_gas(FT_TRANSFER_CALL_GAS)
.with_attached_deposit(1)
.ft_transfer_call(target, amount.into(), None, message),
),
None => ext_bridge_token::ext(self.get_bridge_token_account_id(token))
.with_static_gas(MINT_GAS)
.with_attached_deposit(env::attached_deposit() - required_deposit)
.mint(target, amount.into()),
}
ext_bridge_token::ext(self.get_bridge_token_account_id(token))
.with_static_gas(MINT_GAS + FT_TRANSFER_CALL_GAS)
.with_attached_deposit(env::attached_deposit() - required_deposit)
.mint(target, amount.into(), message)
}

/// Burn given amount of tokens and unlock it on the Ethereum side for the recipient address.
/// We return the amount as u128 and the address of the beneficiary as `[u8; 20]` for ease of
/// processing on Solidity side.
/// Caller must be <token_address>.<current_account_id>, where <token_address> exists in the `tokens`.
#[result_serializer(borsh)]
#[allow(unused_variables)]
pub fn finish_withdraw(
&mut self,
#[serializer(borsh)] sender_id: AccountId,
#[serializer(borsh)] amount: Balance,
#[serializer(borsh)] recipient: String,
) -> ResultType {
Expand Down Expand Up @@ -508,6 +508,26 @@ impl BridgeTokenFactory {
)
}

/// Propose new controller for the provided tokens
///
/// # Arguments
///
/// * `tokens_account_id`: A list of tokens that need their controller updated.
/// * `new_controller`: New controller for tokens
///
#[access_control_any(roles(Role::DAO))]
pub fn propose_new_controller_for_tokens(
&self,
tokens_account_id: Vec<AccountId>,
new_controller: AccountId,
) {
for token_account_id in tokens_account_id {
ext_bridge_token::ext(token_account_id)
.with_static_gas(SET_CONTROLLER_GAS)
.set_new_controller(Some(new_controller.clone()));
}
}

/// Pause the withdraw method in the bridge token contract.
///
/// # Arguments
Expand Down
82 changes: 78 additions & 4 deletions bridge-token/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use near_sdk::{
const FINISH_WITHDRAW_GAS: Gas = Gas(Gas::ONE_TERA.0 * 50);
const OUTER_UPGRADE_GAS: Gas = Gas(Gas::ONE_TERA.0 * 15);
const NO_DEPOSIT: Balance = 0;
const CURRENT_STATE_VERSION: u32 = 1;
const CURRENT_STATE_VERSION: u32 = 2;

pub type Mask = u128;

Expand All @@ -30,13 +30,15 @@ pub struct BridgeToken {
decimals: u8,
paused: Mask,
icon: Option<String>,
new_controller: Option<AccountId>
}

#[ext_contract(ext_bridge_token_factory)]
pub trait ExtBridgeTokenFactory {
#[result_serializer(borsh)]
fn finish_withdraw(
&self,
#[serializer(borsh)] sender_id: AccountId,
#[serializer(borsh)] amount: Balance,
#[serializer(borsh)] recipient: String,
) -> Promise;
Expand Down Expand Up @@ -67,6 +69,7 @@ impl BridgeToken {
decimals: 0,
paused: Mask::default(),
icon: None,
new_controller: None,
}
}

Expand All @@ -91,15 +94,37 @@ impl BridgeToken {
}

#[payable]
pub fn mint(&mut self, account_id: AccountId, amount: U128) {
pub fn mint(&mut self,
account_id: AccountId,
amount: U128,
msg: Option<String>) -> PromiseOrValue<U128> {
assert_eq!(
env::predecessor_account_id(),
self.controller,
"Only controller can call mint"
);

self.storage_deposit(Some(account_id.clone()), None);
self.token.internal_deposit(&account_id, amount.into());
if let Some(msg) = msg {
self.token
.internal_deposit(&env::predecessor_account_id(), amount.into());

self.ft_transfer_call(account_id, amount, None, msg)
} else {
self.token.internal_deposit(&account_id, amount.into());
PromiseOrValue::Value(amount)
}
}

pub fn burn(&mut self, amount: U128) {
assert_eq!(
env::predecessor_account_id(),
self.controller,
"Only controller can call burn"
);

self.token
.internal_withdraw(&env::predecessor_account_id(), amount.into());
}

#[payable]
Expand All @@ -113,7 +138,18 @@ impl BridgeToken {

ext_bridge_token_factory::ext(self.controller.clone())
.with_static_gas(FINISH_WITHDRAW_GAS)
.finish_withdraw(amount.into(), recipient)
.finish_withdraw(env::predecessor_account_id(), amount.into(), recipient)
}

pub fn set_new_controller(&mut self, new_controller: Option<AccountId>) {
require!(self.controller_or_self());
self.new_controller = new_controller;
}

pub fn update_controller(&mut self) {
require!(Some(env::predecessor_account_id()) == self.new_controller);
self.controller = env::predecessor_account_id();
self.new_controller = None;
}

pub fn account_storage_usage(&self) -> StorageUsage {
Expand Down Expand Up @@ -204,6 +240,20 @@ pub struct BridgeTokenV0 {
paused: Mask,
}

#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct BridgeTokenV1 {
controller: AccountId,
token: FungibleToken,
name: String,
symbol: String,
reference: String,
reference_hash: Base64VecU8,
decimals: u8,
paused: Mask,
icon: Option<String>,
}

impl From<BridgeTokenV0> for BridgeToken {
fn from(obj: BridgeTokenV0) -> Self {
#[allow(deprecated)]
Expand All @@ -217,6 +267,25 @@ impl From<BridgeTokenV0> for BridgeToken {
decimals: obj.decimals,
paused: obj.paused,
icon: None,
new_controller: None,
}
}
}

impl From<BridgeTokenV1> for BridgeToken {
fn from(obj: BridgeTokenV1) -> Self {
#[allow(deprecated)]
Self {
controller: obj.controller,
token: obj.token,
name: obj.name,
symbol: obj.symbol,
reference: obj.reference,
reference_hash: obj.reference_hash,
decimals: obj.decimals,
paused: obj.paused,
icon: obj.icon,
new_controller: None,
}
}
}
Expand All @@ -232,6 +301,11 @@ impl BridgeToken {
let new_state: BridgeToken = old_state.into();
assert!(new_state.controller_or_self());
new_state
} else if from_version == 1 {
let old_state: BridgeTokenV1 = env::state_read().expect("Contract isn't initialized");
let new_state: BridgeToken = old_state.into();
assert!(new_state.controller_or_self());
new_state
} else {
env::state_read().unwrap()
}
Expand Down
Binary file modified res/bridge_token.wasm
Binary file not shown.
Binary file modified res/bridge_token_factory.wasm
Binary file not shown.
Binary file modified res/rainbow_bridge_near_token_locker.wasm
Binary file not shown.
Loading