Skip to content

Commit

Permalink
2.3.3: Add ability to transfer NEAR reserve (DAO)
Browse files Browse the repository at this point in the history
  • Loading branch information
Usn Zorro committed Oct 20, 2022
1 parent 6d1d031 commit 68a70b3
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 155 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
edition = "2018"
name = "usn"
version = "2.3.2"
version = "2.3.3"

[lib]
crate-type = ["cdylib"]
Expand Down
130 changes: 10 additions & 120 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use oracle::{ExchangeRate, Oracle, PriceData};
use std::fmt::Debug;

use crate::ft::FungibleTokenFreeStorage;
use stable::{usdt_id, AssetInfo, CommissionRate, OldStableTreasury, StableTreasury};
use stable::{usdt_id, AssetInfo, CommissionRate, StableTreasury};

uint::construct_uint!(
pub struct U256(4);
Expand Down Expand Up @@ -366,125 +366,8 @@ impl Contract {
#[init(ignore_state)]
#[private]
pub fn migrate() -> Self {
use near_sdk::Timestamp;

#[derive(BorshSerialize, BorshDeserialize)]
struct ExchangeRate {
multiplier: u128,
decimals: u8,
timestamp: Timestamp,
recency_duration: Timestamp,
}
#[derive(BorshSerialize, BorshDeserialize)]
struct ExchangeRates {
pub current: ExchangeRate,
pub smooth: ExchangeRate,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct ExponentialSpreadParams {
pub min: f64,
pub max: f64,
pub scaler: f64,
}

#[derive(BorshDeserialize, BorshSerialize)]
enum Spread {
Fixed(Balance),
Exponential(ExponentialSpreadParams),
}

#[derive(BorshDeserialize, BorshSerialize)]
struct CacheItem {
pub timestamp: Timestamp,
pub value: f64,
pub smoothed_value: f64,
pub n: u8,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct IntervalCache {
pub items: Vec<CacheItem>,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct TreasuryData {
pub cache: IntervalCache,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct ExchangeRateValue {
multiplier: U128,
decimals: u8,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct MinMaxRate {
max_previous: Option<ExchangeRateValue>,
max_current: Option<ExchangeRateValue>,
min_previous: Option<ExchangeRateValue>,
min_current: Option<ExchangeRateValue>,
timestamp: Timestamp,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct VolumeCacheItem {
usn: U128,
near: U128,
timestamp: Timestamp,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct VolumeCache {
time_slot: Timestamp,
max_age: Timestamp,
sum_usn: U128,
sum_near: U128,
items: Vec<VolumeCacheItem>,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct VolumeHistory {
pub one_hour: VolumeCache,
pub five_min: VolumeCache,
}

#[derive(BorshDeserialize, BorshSerialize)]
struct PrevContract {
owner_id: AccountId,
proposed_owner_id: AccountId,
guardians: UnorderedSet<AccountId>,
token: FungibleTokenFreeStorage,
metadata: LazyOption<FungibleTokenMetadata>,
black_list: LookupMap<AccountId, BlackListStatus>,
status: ContractStatus,
oracle: Oracle,
spread: Spread,
commission: CommissionV1,
treasury: LazyOption<TreasuryData>,
usn2near: VolumeHistory,
near2usn: VolumeHistory,
best_rate: MinMaxRate,
stable_treasury: OldStableTreasury,
}

let mut prev: PrevContract = env::state_read().expect("Contract is not initialized");

Self {
owner_id: prev.owner_id,
proposed_owner_id: prev.proposed_owner_id,
guardians: prev.guardians,
token: prev.token,
metadata: prev.metadata,
black_list: prev.black_list,
status: prev.status,
commission: prev.commission,
stable_treasury: StableTreasury::from_old(
&mut prev.stable_treasury,
StorageKey::StableTreasury,
),
oracle: prev.oracle,
}
let prev: Contract = env::state_read().expect("Contract is not initialized");
prev
}

fn abort_if_pause(&self) {
Expand Down Expand Up @@ -806,6 +689,13 @@ impl Contract {
self.token.internal_deposit(&account_id, amount);
event::emit::ft_mint(&account_id, amount, None);
}

#[payable]
pub fn transfer_near(&mut self, account_id: AccountId, amount: U128) -> Promise {
assert_one_yocto();
self.assert_owner();
Promise::new(account_id).transfer(amount.into())
}
}

#[cfg(all(test, not(target_arch = "wasm32")))]
Expand Down
34 changes: 0 additions & 34 deletions src/stable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,6 @@ impl Default for CommissionRate {
}
}

#[derive(BorshDeserialize, BorshSerialize)]
pub struct OldAssetInfo {
decimals: u8,
commission: U128,
status: AssetStatus,
}

#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Debug)]
#[serde(crate = "near_sdk::serde")]
pub struct AssetInfo {
Expand Down Expand Up @@ -87,20 +80,6 @@ impl AssetInfo {
}
}

fn copy_asset_info(old_asset_info: &OldAssetInfo) -> AssetInfo {
AssetInfo {
decimals: old_asset_info.decimals,
status: old_asset_info.status.clone(),
commission: old_asset_info.commission,
commission_rate: CommissionRate::default(),
}
}

#[derive(BorshDeserialize, BorshSerialize)]
pub struct OldStableTreasury {
stable_token: UnorderedMap<AccountId, OldAssetInfo>,
}

#[derive(BorshDeserialize, BorshSerialize)]
pub struct StableTreasury {
assets: UnorderedMap<AccountId, AssetInfo>,
Expand Down Expand Up @@ -297,19 +276,6 @@ impl StableTreasury {
let asset_info = self.assets.get(asset_id).unwrap();
asset_info.commission_rate
}

pub fn from_old<S>(old_treasury: &mut OldStableTreasury, prefix: S) -> Self
where
S: IntoStorageKey,
{
let old_assets = old_treasury.stable_token.to_vec();
old_treasury.stable_token.clear();
let mut new_assets = UnorderedMap::new(prefix);
for (asset_id, old_asset_info) in old_assets.iter() {
new_assets.insert(&asset_id.clone(), &copy_asset_info(old_asset_info));
}
StableTreasury { assets: new_assets }
}
}

#[cfg(all(test, not(target_arch = "wasm32")))]
Expand Down
1 change: 1 addition & 0 deletions tests/sandbox-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const usnMethods = {
'transfer_commission',
'add_stable_asset',
'mint_by_near',
'transfer_near',
],
};

Expand Down
54 changes: 54 additions & 0 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1366,3 +1366,57 @@ describe('Staking Pool', async function () {
);
});
});

describe('Transfer NEAR', function () {
this.timeout(15000);

it('should fail being called not by owner', async () => {
await assert.rejects(
async () => {
await global.aliceContract.transfer_near({
args: {
account_id: config.aliceId,
amount: TEN_NEARS,
},
amount: ONE_YOCTO,
gas: GAS_FOR_CALL,
});
},
(err) => {
assert.match(err.message, /This method can be called only by owner/);
return true;
}
);
});

it('should transfer certain amount of NEAR', async () => {
const nearAliceBalanceBefore = await global.aliceAccount.state();
const nearUsnBalanceBefore = await global.usnAccount.state();

await global.usnContract.transfer_near({
args: {
account_id: config.aliceId,
amount: TEN_NEARS,
},
amount: ONE_YOCTO,
gas: GAS_FOR_CALL,
});

const nearAliceBalanceAfter = await global.aliceAccount.state();
const nearUsnBalanceAfter = await global.usnAccount.state();

const aliceBalanceDifference = new BN(nearAliceBalanceAfter.amount)
.sub(new BN(nearAliceBalanceBefore.amount));
const usnBalanceDifference = new BN(nearUsnBalanceBefore.amount)
.sub(new BN(nearUsnBalanceAfter.amount));

assert(new BN(TEN_NEARS)
.sub(aliceBalanceDifference)
.lt(new BN('10000000000000000000000')) // Transfer loss < 0.01 NEAR
);
assert(new BN(TEN_NEARS)
.sub(usnBalanceDifference)
.lt(new BN('1000000000000000000000')) // Transfer loss < 0.001 NEAR
);
});
});

0 comments on commit 68a70b3

Please sign in to comment.