Skip to content

Commit 81479f8

Browse files
authored
Merge pull request #102 from RealisNetwork/hot-fix/add-ft-freeze
Hot fix/add ft freeze
2 parents 97a9b1b + 5ec047a commit 81479f8

File tree

10 files changed

+107
-24
lines changed

10 files changed

+107
-24
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ft-lockup-contract/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl Contract {
107107

108108
impl Contract {
109109
pub fn next_index(&mut self) -> LockupIndex {
110-
while self.lockups.keys().any(|key| key == self.index) {
110+
if self.lockups.get(&self.index).is_some() {
111111
self.index = self
112112
.index
113113
.checked_add(1)

ft-token-contract/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ft-token-contract"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
edition = "2021"
55

66
[lib]

ft-token-contract/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ pub const DEFAULT_MINT_AMOUNT: u128 = 3_000_000_000 * 10_u128.pow(12);
2424
pub struct Contract {
2525
pub owner_id: AccountId,
2626
pub staking_contract: AccountId,
27+
pub lockup_contract: AccountId,
2728
pub ft: FungibleToken,
2829
pub last_mint: Timestamp,
2930
pub backend: UnorderedSet<AccountId>,
31+
pub suspensioned_accounts: UnorderedSet<AccountId>,
3032
}
3133

3234
#[near_bindgen]
@@ -36,21 +38,25 @@ impl Contract {
3638
owner_id: Option<AccountId>,
3739
backend_ids: Option<Vec<AccountId>>,
3840
staking_id: AccountId,
41+
lockup_id: AccountId,
3942
) -> Self {
4043
let owner_id = owner_id.unwrap_or_else(env::predecessor_account_id);
4144
let mut this = Self {
4245
owner_id: owner_id.clone(),
4346
staking_contract: staking_id.clone(),
47+
lockup_contract: lockup_id.clone(),
4448
ft: FungibleToken::new(b"a".to_vec()),
4549
last_mint: env::block_timestamp(),
4650
backend: UnorderedSet::new(b"b".to_vec()),
51+
suspensioned_accounts: UnorderedSet::new(b"c".to_vec()),
4752
};
4853

4954
this.backend
5055
.extend(backend_ids.unwrap_or_default().into_iter());
5156

5257
this.ft.internal_register_account(&owner_id);
5358
this.ft.internal_register_account(&staking_id);
59+
this.ft.internal_register_account(&lockup_id);
5460

5561
this.ft.internal_deposit(&owner_id, DEFAULT_MINT_AMOUNT);
5662
near_contract_standards::fungible_token::events::FtMint {

ft-token-contract/src/lis_token.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,13 @@ mod tests {
104104
fn mint_time_check() {
105105
let owner_id = accounts(0);
106106
let staking_id = accounts(1);
107+
let lockup_id = accounts(2);
107108
let initial_total_supply = 3_000_000_000 * 10_u128.pow(12);
108109
let context = VMContextBuilder::new();
109110

110111
// init contract
111112
testing_env!(context.clone().block_timestamp(WEEK.0).build());
112-
let mut contract = Contract::new(Some(owner_id.clone()), None, staking_id);
113+
let mut contract = Contract::new(Some(owner_id.clone()), None, staking_id, lockup_id);
113114
assert_eq!(contract.ft_total_supply().0, initial_total_supply);
114115

115116
// wait week
@@ -170,12 +171,13 @@ mod tests {
170171
fn mint_before_new_week() {
171172
let owner_id = accounts(0);
172173
let staking_id = accounts(1);
174+
let lockup_id = accounts(2);
173175
let initial_total_supply = 3_000_000_000 * 10_u128.pow(12);
174176
let context = VMContextBuilder::new();
175177

176178
// init contract
177179
testing_env!(context.clone().block_timestamp(WEEK.0).build());
178-
let mut contract = Contract::new(Some(owner_id.clone()), None, staking_id);
180+
let mut contract = Contract::new(Some(owner_id.clone()), None, staking_id, lockup_id);
179181
assert_eq!(contract.ft_total_supply().0, initial_total_supply);
180182

181183
// wait 3 days
@@ -193,11 +195,12 @@ mod tests {
193195
fn can_mint_only_owner() {
194196
let owner_id = accounts(0);
195197
let staking_id = accounts(1);
198+
let lockup_id = accounts(2);
196199
let context = VMContextBuilder::new();
197200

198201
// init contract
199202
testing_env!(context.clone().block_timestamp(WEEK.0).build());
200-
let mut contract = Contract::new(Some(owner_id.clone()), None, staking_id);
203+
let mut contract = Contract::new(Some(owner_id.clone()), None, staking_id, lockup_id);
201204

202205
// wait week
203206
testing_env!(context

ft-token-contract/src/owner.rs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
use crate::*;
2-
use near_contract_standards::upgrade::Ownable;
3-
use near_sdk::assert_one_yocto;
2+
use near_contract_standards::{
3+
fungible_token::{receiver::ext_ft_receiver, resolver::ext_ft_resolver},
4+
upgrade::Ownable,
5+
};
6+
use near_sdk::{assert_one_yocto, env, json_types::U128, Gas, Promise};
7+
8+
#[near_bindgen]
9+
impl Ownable for Contract {
10+
fn get_owner(&self) -> AccountId {
11+
self.owner_id.clone()
12+
}
13+
14+
fn set_owner(&mut self, owner: AccountId) {
15+
self.assert_owner();
16+
self.owner_id = owner;
17+
}
18+
}
419

520
#[near_bindgen]
621
impl Contract {
@@ -25,4 +40,43 @@ impl Contract {
2540
pub fn get_backend_accounts(&self) -> Vec<AccountId> {
2641
self.backend.iter().collect()
2742
}
43+
44+
#[payable]
45+
pub fn ft_freeze_call(
46+
&mut self,
47+
account_id: AccountId,
48+
amount: U128,
49+
memo: Option<String>,
50+
msg: String,
51+
) -> Promise {
52+
assert_one_yocto();
53+
self.assert_owner();
54+
55+
require!(
56+
self.suspensioned_accounts.contains(&account_id),
57+
"Not suspensioned account"
58+
);
59+
require!(
60+
env::prepaid_gas() > GAS_FOR_FT_TRANSFER_CALL,
61+
"More gas is required"
62+
);
63+
64+
const GAS_FOR_RESOLVE_TRANSFER: Gas = Gas(5_000_000_000_000);
65+
const GAS_FOR_FT_TRANSFER_CALL: Gas = Gas(25_000_000_000_000 + GAS_FOR_RESOLVE_TRANSFER.0);
66+
67+
let receiver_id = self.lockup_contract.clone();
68+
let sender_id = account_id;
69+
let amount: Balance = amount.into();
70+
self.ft
71+
.internal_transfer(&sender_id, &receiver_id, amount, memo);
72+
// Initiating receiver's call and the callback
73+
ext_ft_receiver::ext(receiver_id.clone())
74+
.with_static_gas(env::prepaid_gas() - GAS_FOR_FT_TRANSFER_CALL)
75+
.ft_on_transfer(env::predecessor_account_id(), amount.into(), msg)
76+
.then(
77+
ext_ft_resolver::ext(env::current_account_id())
78+
.with_static_gas(GAS_FOR_RESOLVE_TRANSFER)
79+
.ft_resolve_transfer(sender_id, receiver_id, amount.into()),
80+
)
81+
}
2882
}

ft-token-contract/src/update.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,40 @@
11
use crate::*;
2-
use near_contract_standards::upgrade::Ownable;
32

4-
#[near_bindgen]
5-
impl Ownable for Contract {
6-
fn get_owner(&self) -> AccountId {
7-
self.owner_id.clone()
8-
}
3+
// pub struct Contract {
4+
// pub owner_id: AccountId,
5+
// pub staking_contract: AccountId,
6+
// pub lockup_contract: AccountId,
7+
// pub ft: FungibleToken,
8+
// pub last_mint: Timestamp,
9+
// pub backend: UnorderedSet<AccountId>,
10+
// pub suspensioned_accounts: UnorderedSet<AccountId>,
11+
// }
912

10-
fn set_owner(&mut self, owner: AccountId) {
11-
self.assert_owner();
12-
self.owner_id = owner;
13-
}
13+
#[derive(BorshDeserialize, BorshSerialize)]
14+
pub struct ContractV010 {
15+
pub owner_id: AccountId,
16+
pub staking_contract: AccountId,
17+
pub ft: FungibleToken,
18+
pub last_mint: Timestamp,
19+
pub backend: UnorderedSet<AccountId>,
1420
}
1521

1622
#[near_bindgen]
1723
impl Contract {
1824
#[private]
1925
#[init(ignore_state)]
20-
pub fn update() -> Self {
21-
env::state_read().unwrap_or_else(|| env::panic_str("Not initialized"))
26+
pub fn update(lockup_id: AccountId, suspensioned_accounts: Vec<AccountId>) -> Self {
27+
let contract_old: ContractV010 = env::state_read().unwrap();
28+
let mut this = Self {
29+
owner_id: contract_old.owner_id,
30+
staking_contract: contract_old.staking_contract,
31+
lockup_contract: lockup_id,
32+
ft: contract_old.ft,
33+
last_mint: contract_old.last_mint,
34+
backend: contract_old.backend,
35+
suspensioned_accounts: UnorderedSet::new(b"c".to_vec()),
36+
};
37+
this.suspensioned_accounts.extend(suspensioned_accounts);
38+
this
2239
}
2340
}

ft-token-contract/tests/utils.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,23 @@ use workspaces::{network::Sandbox, AccountId, Contract, Worker};
44

55
pub const CONTRACT_ACCOUNT: &str = "token.v1.realisnetwork.near";
66
pub const STAKING_ACCOUNT: &str = "staking.v1.realisnetwork.near";
7+
pub const LOCKUP_ACCOUNT: &str = "lockup.v1.realisnetwork.near";
78
pub const SPEC_METADATA: &str = "ft-1.0.1";
89

910
pub async fn pull_contract(worker: &Worker<Sandbox>) -> anyhow::Result<Contract> {
1011
let mainnet = workspaces::mainnet_archival().await?;
1112
let contract_id: AccountId = CONTRACT_ACCOUNT.parse()?;
1213
let contract = worker
1314
.import_contract(&contract_id, &mainnet)
14-
.initial_balance(parse_near!("1000 N"))
15+
.initial_balance(parse_near!("5000 N"))
1516
.transact()
1617
.await?;
1718

1819
contract
1920
.call("new")
20-
.args_json(serde_json::json!({ "staking_id": STAKING_ACCOUNT }))
21+
.args_json(
22+
serde_json::json!({ "staking_id": STAKING_ACCOUNT, "lockup_id": LOCKUP_ACCOUNT }),
23+
)
2124
.transact()
2225
.await?
2326
.into_result()?;

scripts/deploy.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ then
112112
--initArgs '{"token_account_id": "'$TOKEN_CONTRACT_ID'", "deposit_whitelist": ["'$OWNER_ID'", "'$STAKING_CONTRACT_ID'"]}' \
113113
--initGas 300000000000000
114114
echo "Register in token contract"
115-
near call $TOKEN_CONTRACT_ID register '{"account_id": "'$LOCKUP_CONTRACT_ID'"}' --accountId $OWNER_ID
115+
near call $TOKEN_CONTRACT_ID storage_deposit '{"account_id": "'$LOCKUP_CONTRACT_ID'"}' --accountId $OWNER_ID --deposit 1
116116
else
117117
echo "Updating contract"
118118
echo y | near deploy --accountId $LOCKUP_CONTRACT_ID \

test-utils/src/token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub async fn pull(
3535
let contract_id: AccountId = TOKEN_CONTRACT_ACCOUNT.parse()?;
3636
let contract = worker
3737
.import_contract(&contract_id, &mainnet)
38-
.initial_balance(parse_near!("1000 N"))
38+
.initial_balance(parse_near!("5000 N"))
3939
.transact()
4040
.await?;
4141

0 commit comments

Comments
 (0)