Skip to content

Commit

Permalink
fix whitelisted_postfix (#110)
Browse files Browse the repository at this point in the history
* fix identity verification for the whitelisted_postfix related interfaces.

* add donation functions and mft_unregister

* update mft_unregister

* update donation functions

* add comments to the donation functions.
  • Loading branch information
MagicGordon authored Oct 11, 2024
1 parent 9d853b0 commit 4bf8df2
Show file tree
Hide file tree
Showing 18 changed files with 317 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ref-exchange/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ref-exchange"
version = "1.9.6"
version = "1.9.7"
authors = ["Illia Polosukhin <[email protected]>"]
edition = "2018"
publish = false
Expand Down
8 changes: 8 additions & 0 deletions ref-exchange/release_notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Release Notes

### Version 1.9.7
```
CMN4goNWHQjsXevLbqAC9nXKTw1yeJqysEfB647uuyro
```
1. fix identity verification for the whitelisted_postfix related functions.
2. add donation functions.
3. add mft_unregister.

### Version 1.9.6
```
2Yo8qJ5S3biFJbnBdb4ZNcGhN1RhHJq34cGF4g7Yigcw
Expand Down
7 changes: 7 additions & 0 deletions ref-exchange/src/degen_swap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,13 @@ impl DegenSwapPool {
self.shares.insert(account_id, &0);
}

/// Unregister account with shares balance of 0.
/// The storage should be refunded to the user.
pub fn share_unregister(&mut self, account_id: &AccountId) {
let shares = self.shares.remove(account_id);
assert!(shares.expect(ERR13_LP_NOT_REGISTERED) == 0, "{}", ERR19_NONZERO_LP_SHARES);
}

/// Transfers shares from predecessor to receiver.
pub fn share_transfer(&mut self, sender_id: &AccountId, receiver_id: &AccountId, amount: u128) {
let balance = self.shares.get(&sender_id).expect(ERR13_LP_NOT_REGISTERED);
Expand Down
65 changes: 65 additions & 0 deletions ref-exchange/src/donation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use crate::*;

#[near_bindgen]
impl Contract {
/// The user donates the shares they hold to the protocol.
///
/// # Arguments
///
/// * `pool_id` - The pool id where the shares are located.
/// * `amount` - The donation amount; if it's None, the entire amount will be donated.
/// * `unregister` - If `Some(true)`, Will attempt to unregister the shares and refund the user’s storage fees.
/// The storage fee will be refunded to the user's internal account first;
/// if there is no internal account, a transfer will be initiated.
#[payable]
pub fn donation_share(&mut self, pool_id: u64, amount: Option<U128>, unregister: Option<bool>) {
assert_one_yocto();
self.assert_contract_running();
let account_id = env::predecessor_account_id();
let prev_storage = env::storage_usage();
let mut pool = self.pools.get(pool_id).expect(ERR85_NO_POOL);
let donation_amount = amount.map(|v| v.0).unwrap_or(pool.share_balances(&account_id));
assert!(donation_amount > 0, "Invalid amount");
pool.share_transfer(&account_id, &env::current_account_id(), donation_amount);
if unregister == Some(true) {
pool.share_unregister(&account_id);
}
self.pools.replace(pool_id, &pool);
if prev_storage > env::storage_usage() {
let refund = (prev_storage - env::storage_usage()) as Balance * env::storage_byte_cost();
if let Some(mut account) = self.internal_get_account(&account_id) {
account.near_amount += refund;
self.internal_save_account(&account_id, account);
} else {
Promise::new(account_id.clone()).transfer(refund);
}
}
event::Event::DonationShare { account_id: &account_id, pool_id, amount: U128(donation_amount) }.emit();
}

/// The user donates the tokens they hold to the owner.
///
/// # Arguments
///
/// * `token_id` - The id of the donated token.
/// * `amount` - The donation amount; if it's None, the entire amount will be donated.
/// * `unregister` - If `Some(true)`, Will attempt to unregister the tokens.
#[payable]
pub fn donation_token(&mut self, token_id: ValidAccountId, amount: Option<U128>, unregister: Option<bool>) {
assert_one_yocto();
self.assert_contract_running();
let account_id = env::predecessor_account_id();
let mut account = self.internal_unwrap_account(&account_id);
let donation_amount = amount.map(|v| v.0).unwrap_or(account.get_balance(token_id.as_ref()).expect("Invalid token_id"));
assert!(donation_amount > 0, "Invalid amount");
account.withdraw(token_id.as_ref(), donation_amount);
if unregister == Some(true) {
account.unregister(token_id.as_ref());
}
self.internal_save_account(&account_id, account);
let mut owner_account = self.internal_unwrap_account(&self.owner_id);
owner_account.deposit(token_id.as_ref(), donation_amount);
self.accounts.insert(&self.owner_id, &owner_account.into());
event::Event::DonationToken { account_id: &account_id, token_id: token_id.as_ref(), amount: U128(donation_amount) }.emit();
}
}
2 changes: 2 additions & 0 deletions ref-exchange/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub const ERR15_NO_STORAGE_CAN_WITHDRAW: &str = "E15: no storage can withdraw";
pub const ERR16_STORAGE_WITHDRAW_TOO_MUCH: &str = "E16: storage withdraw too much";
pub const ERR17_DEPOSIT_LESS_THAN_MIN_STORAGE: &str = "E17: deposit less than min storage";
pub const ERR18_TOKENS_NOT_EMPTY: &str = "E18: storage unregister tokens not empty";
pub const ERR19_NONZERO_LP_SHARES: &str = "E19: Nonzero LP shares";

// Accounts.

Expand Down Expand Up @@ -90,6 +91,7 @@ pub const ERR105_WHITELISTED_POSTFIX_NOT_IN_LIST: &str = "E105: whitelisted post

//mft
pub const ERR110_INVALID_REGISTER: &str = "E110: Invalid register";
pub const ERR111_INVALID_UNREGISTER: &str = "E111: Invalid unregister";

// rated pool
pub const ERR120_RATES_EXPIRED: &str = "E120: Rates expired";
Expand Down
38 changes: 38 additions & 0 deletions ref-exchange/src/event.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

use crate::*;
use near_sdk::serde_json::json;

const EVENT_STANDARD: &str = "exchange.ref";
const EVENT_STANDARD_VERSION: &str = "1.0.0";

#[derive(Serialize, Debug, Clone)]
#[serde(crate = "near_sdk::serde")]
#[serde(tag = "event", content = "data")]
#[serde(rename_all = "snake_case")]
#[must_use = "Don't forget to `.emit()` this event"]
pub enum Event<'a> {
DonationShare {
account_id: &'a AccountId,
pool_id: u64,
amount: U128,
},
DonationToken {
account_id: &'a AccountId,
token_id: &'a AccountId,
amount: U128,
}
}

impl Event<'_> {
pub fn emit(&self) {
let data = json!(self);
let event_json = json!({
"standard": EVENT_STANDARD,
"version": EVENT_STANDARD_VERSION,
"event": data["event"],
"data": [data["data"]]
})
.to_string();
log!("EVENT_JSON:{}", event_json);
}
}
2 changes: 2 additions & 0 deletions ref-exchange/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ mod shadow_actions;
mod unit_lpt_cumulative_infos;
mod pool_limit_info;
mod client_echo_limit;
mod donation;
mod event;

near_sdk::setup_alloc!();

Expand Down
21 changes: 21 additions & 0 deletions ref-exchange/src/multi_fungible_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,27 @@ impl Contract {
}
}

/// Unregister LP token of given pool for given account.
#[payable]
pub fn mft_unregister(&mut self, token_id: String) {
assert_one_yocto();
self.assert_contract_running();
let account_id = env::predecessor_account_id();
let prev_storage = env::storage_usage();
match parse_token_id(token_id) {
TokenOrPool::Token(_) => env::panic(ERR111_INVALID_UNREGISTER.as_bytes()),
TokenOrPool::Pool(pool_id) => {
let mut pool = self.pools.get(pool_id).expect(ERR85_NO_POOL);
pool.share_unregister(&account_id);
self.pools.replace(pool_id, &pool);
if prev_storage > env::storage_usage() {
let refund = (prev_storage - env::storage_usage()) as Balance * env::storage_byte_cost();
Promise::new(account_id).transfer(refund);
}
}
}
}

/// Transfer one of internal tokens: LP or balances.
/// `token_id` can either by account of the token or pool number.
#[payable]
Expand Down
7 changes: 3 additions & 4 deletions ref-exchange/src/owner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl Contract {
#[payable]
pub fn extend_auto_whitelisted_postfix(&mut self, postfixes: Vec<String>) {
assert_one_yocto();
self.is_owner_or_guardians();
assert!(self.is_owner_or_guardians(), "{}", ERR100_NOT_ALLOWED);
for postfix in postfixes {
self.auto_whitelisted_postfix.insert(postfix.clone());
}
Expand All @@ -84,7 +84,7 @@ impl Contract {
#[payable]
pub fn remove_auto_whitelisted_postfix(&mut self, postfixes: Vec<String>) {
assert_one_yocto();
self.is_owner_or_guardians();
assert!(self.is_owner_or_guardians(), "{}", ERR100_NOT_ALLOWED);
for postfix in postfixes {
let exist = self.auto_whitelisted_postfix.remove(&postfix);
assert!(exist, "{}", ERR105_WHITELISTED_POSTFIX_NOT_IN_LIST);
Expand Down Expand Up @@ -300,9 +300,8 @@ impl Contract {
assert!(amount > 0, "{}", ERR29_ILLEGAL_WITHDRAW_AMOUNT);
let owner_id = self.owner_id.clone();
let mut account = self.internal_unwrap_account(&owner_id);
// Note: subtraction and deregistration will be reverted if the promise fails.
account.withdraw(&token_id, amount);
self.internal_save_account(&owner_id, account);
self.accounts.insert(&owner_id, &account.into());
self.internal_send_tokens(&owner_id, &token_id, amount, skip_unwrap_near)
}

Expand Down
9 changes: 9 additions & 0 deletions ref-exchange/src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,15 @@ impl Pool {
}
}

pub fn share_unregister(&mut self, account_id: &AccountId) {
match self {
Pool::SimplePool(pool) => pool.share_unregister(account_id),
Pool::StableSwapPool(pool) => pool.share_unregister(account_id),
Pool::RatedSwapPool(pool) => pool.share_unregister(account_id),
Pool::DegenSwapPool(pool) => pool.share_unregister(account_id),
}
}

pub fn predict_add_rated_liquidity(
&self,
amounts: &Vec<Balance>,
Expand Down
7 changes: 7 additions & 0 deletions ref-exchange/src/rated_swap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,13 @@ impl RatedSwapPool {
self.shares.insert(account_id, &0);
}

/// Unregister account with shares balance of 0.
/// The storage should be refunded to the user.
pub fn share_unregister(&mut self, account_id: &AccountId) {
let shares = self.shares.remove(account_id);
assert!(shares.expect(ERR13_LP_NOT_REGISTERED) == 0, "{}", ERR19_NONZERO_LP_SHARES);
}

/// Transfers shares from predecessor to receiver.
pub fn share_transfer(&mut self, sender_id: &AccountId, receiver_id: &AccountId, amount: u128) {
let balance = self.shares.get(&sender_id).expect(ERR13_LP_NOT_REGISTERED);
Expand Down
7 changes: 7 additions & 0 deletions ref-exchange/src/simple_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ impl SimplePool {
self.shares.insert(account_id, &0);
}

/// Unregister account with shares balance of 0.
/// The storage should be refunded to the user.
pub fn share_unregister(&mut self, account_id: &AccountId) {
let shares = self.shares.remove(account_id);
assert!(shares.expect(ERR13_LP_NOT_REGISTERED) == 0, "{}", ERR19_NONZERO_LP_SHARES);
}

/// Transfers shares from predecessor to receiver.
pub fn share_transfer(&mut self, sender_id: &AccountId, receiver_id: &AccountId, amount: u128) {
let balance = self.shares.get(&sender_id).expect(ERR13_LP_NOT_REGISTERED);
Expand Down
7 changes: 7 additions & 0 deletions ref-exchange/src/stable_swap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,13 @@ impl StableSwapPool {
self.shares.insert(account_id, &0);
}

/// Unregister account with shares balance of 0.
/// The storage should be refunded to the user.
pub fn share_unregister(&mut self, account_id: &AccountId) {
let shares = self.shares.remove(account_id);
assert!(shares.expect(ERR13_LP_NOT_REGISTERED) == 0, "{}", ERR19_NONZERO_LP_SHARES);
}

/// Transfers shares from predecessor to receiver.
pub fn share_transfer(&mut self, sender_id: &AccountId, receiver_id: &AccountId, amount: u128) {
let balance = self.shares.get(&sender_id).expect(ERR13_LP_NOT_REGISTERED);
Expand Down
Loading

0 comments on commit 4bf8df2

Please sign in to comment.