Skip to content

Commit

Permalink
Merge branch 'master' into feature/aliasing-macro
Browse files Browse the repository at this point in the history
  • Loading branch information
frol authored Feb 19, 2024
2 parents 7628b56 + c522c19 commit b074fc8
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 5 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ jobs:
- uses: Swatinem/rust-cache@v1
- name: Downgrade dependencies
run: |
cargo update -p clap@4.5.0 --precise 4.4.18
cd examples/adder && cargo update -p clap@4.5.0 --precise 4.4.18
cargo update -p clap@4.5.1 --precise 4.4.18
cd examples/adder && cargo update -p clap@4.5.1 --precise 4.4.18
- name: test
run: cargo test --all --features unstable,legacy
lint:
Expand Down Expand Up @@ -79,4 +79,4 @@ jobs:
- name: Install Audit
run: cargo install cargo-audit
- name: Run Audit
run: cargo audit
run: cargo audit
183 changes: 182 additions & 1 deletion examples/fungible-token/tests/workspaces.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use near_sdk::json_types::U128;
use near_workspaces::operations::Function;
use near_workspaces::result::ValueOrReceiptId;
use near_workspaces::{Account, AccountId, Contract, DevNetwork, Worker, types::NearToken};
use near_workspaces::{types::NearToken, Account, AccountId, Contract, DevNetwork, Worker};

const ONE_YOCTO: NearToken = NearToken::from_yoctonear(1);

Expand Down Expand Up @@ -70,6 +70,187 @@ async fn test_total_supply() -> anyhow::Result<()> {
Ok(())
}

#[tokio::test]
async fn test_storage_deposit_not_enough_deposit() -> anyhow::Result<()> {
let initial_balance = U128::from(NearToken::from_near(10000).as_yoctonear());
let worker = near_workspaces::sandbox().await?;
let (contract, _, _) = init(&worker, initial_balance).await?;

let new_account = contract
.as_account()
.create_subaccount("new-account")
.initial_balance(NearToken::from_near(10))
.transact()
.await?
.into_result()?;

let new_account_balance_before_deposit = new_account.view_account().await?.balance;
let contract_balance_before_deposit = contract.view_account().await?.balance;

let minimal_deposit = near_sdk::env::storage_byte_cost().saturating_mul(125);
let res = new_account
.call(contract.id(), "storage_deposit")
.args(b"{}".to_vec())
.max_gas()
.deposit(minimal_deposit.saturating_sub(NearToken::from_yoctonear(1)))
.transact()
.await?;
assert!(res.is_failure());

let new_account_balance_diff = new_account_balance_before_deposit
.saturating_sub(new_account.view_account().await?.balance);
// new_account is charged the transaction fee, so it should loose some NEAR
assert!(new_account_balance_diff > NearToken::from_near(0));
assert!(new_account_balance_diff < NearToken::from_millinear(1));

let contract_balance_diff =
contract.view_account().await?.balance.saturating_sub(contract_balance_before_deposit);
// contract receives a gas rewards for the function call, so it should gain some NEAR
assert!(contract_balance_diff > NearToken::from_near(0));
assert!(contract_balance_diff < NearToken::from_yoctonear(30_000_000_000_000_000_000));

Ok(())
}

#[tokio::test]
async fn test_storage_deposit_minimal_deposit() -> anyhow::Result<()> {
let initial_balance = U128::from(NearToken::from_near(10000).as_yoctonear());
let worker = near_workspaces::sandbox().await?;
let (contract, _, _) = init(&worker, initial_balance).await?;

let new_account = contract
.as_account()
.create_subaccount("new-account")
.initial_balance(NearToken::from_near(10))
.transact()
.await?
.into_result()?;

let new_account_balance_before_deposit = new_account.view_account().await?.balance;
let contract_balance_before_deposit = contract.view_account().await?.balance;

let minimal_deposit = near_sdk::env::storage_byte_cost().saturating_mul(125);
new_account
.call(contract.id(), "storage_deposit")
.args(b"{}".to_vec())
.max_gas()
.deposit(minimal_deposit)
.transact()
.await?
.into_result()?;

let new_account_balance_diff = new_account_balance_before_deposit
.saturating_sub(new_account.view_account().await?.balance);
// new_account is charged the transaction fee, so it should loose a bit more than minimal_deposit
assert!(new_account_balance_diff > minimal_deposit);
assert!(
new_account_balance_diff < minimal_deposit.saturating_add(NearToken::from_millinear(1))
);

let contract_balance_diff =
contract.view_account().await?.balance.saturating_sub(contract_balance_before_deposit);
// contract receives a gas rewards for the function call, so the difference should be slightly more than minimal_deposit
assert!(contract_balance_diff > minimal_deposit);
assert!(
contract_balance_diff
< minimal_deposit.saturating_add(NearToken::from_yoctonear(30_000_000_000_000_000_000))
);

Ok(())
}

#[tokio::test]
async fn test_storage_deposit_refunds_excessive_deposit() -> anyhow::Result<()> {
let initial_balance = U128::from(NearToken::from_near(10000).as_yoctonear());
let worker = near_workspaces::sandbox().await?;
let (contract, _, _) = init(&worker, initial_balance).await?;

let minimal_deposit = near_sdk::env::storage_byte_cost().saturating_mul(125);

// Check the storage balance bounds to make sure we have the right minimal deposit
//
#[derive(near_sdk::serde::Serialize, near_sdk::serde::Deserialize)]
#[serde(crate = "near_sdk::serde")]
struct StorageBalanceBounds {
min: U128,
max: U128,
}
let storage_balance_bounds: StorageBalanceBounds =
contract.call("storage_balance_bounds").view().await?.json()?;
assert_eq!(storage_balance_bounds.min, minimal_deposit.as_yoctonear().into());
assert_eq!(storage_balance_bounds.max, minimal_deposit.as_yoctonear().into());

// Check that a non-registerred account does not have storage balance
//
#[derive(near_sdk::serde::Serialize, near_sdk::serde::Deserialize)]
#[serde(crate = "near_sdk::serde")]
struct StorageBalanceOf {
total: U128,
available: U128,
}
let storage_balance_bounds: Option<StorageBalanceOf> = contract
.call("storage_balance_of")
.args_json(near_sdk::serde_json::json!({"account_id": "non-registerred-account"}))
.view()
.await?
.json()?;
assert!(storage_balance_bounds.is_none());

// Create a new account and deposit some NEAR to cover the storage
//
let new_account = contract
.as_account()
.create_subaccount("new-account")
.initial_balance(NearToken::from_near(10))
.transact()
.await?
.into_result()?;

let new_account_balance_before_deposit = new_account.view_account().await?.balance;
let contract_balance_before_deposit = contract.view_account().await?.balance;

new_account
.call(contract.id(), "storage_deposit")
.args(b"{}".to_vec())
.max_gas()
.deposit(NearToken::from_near(5))
.transact()
.await?
.into_result()?;

// The expected storage balance should be the minimal deposit,
// the balance of the account should be reduced by the deposit,
// and the contract should gain the deposit.
//
let storage_balance_bounds: StorageBalanceOf = contract
.call("storage_balance_of")
.args_json(near_sdk::serde_json::json!({"account_id": new_account.id()}))
.view()
.await?
.json()?;
assert_eq!(storage_balance_bounds.total, minimal_deposit.as_yoctonear().into());
assert_eq!(storage_balance_bounds.available, 0.into());

let new_account_balance_diff = new_account_balance_before_deposit
.saturating_sub(new_account.view_account().await?.balance);
// new_account is charged the transaction fee, so it should loose a bit more than minimal_deposit
assert!(new_account_balance_diff > minimal_deposit);
assert!(
new_account_balance_diff < minimal_deposit.saturating_add(NearToken::from_millinear(1))
);

let contract_balance_diff =
contract.view_account().await?.balance.saturating_sub(contract_balance_before_deposit);
// contract receives a gas rewards for the function call, so the difference should be slightly more than minimal_deposit
assert!(contract_balance_diff > minimal_deposit);
assert!(
contract_balance_diff
< minimal_deposit.saturating_add(NearToken::from_yoctonear(30_000_000_000_000_000_000))
);

Ok(())
}

#[tokio::test]
async fn test_simple_transfer() -> anyhow::Result<()> {
let initial_balance = U128::from(NearToken::from_near(10000).as_yoctonear());
Expand Down
2 changes: 1 addition & 1 deletion near-contract-standards/src/fungible_token/storage_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl StorageManagement for FungibleToken {
}

self.internal_register_account(&account_id);
let refund = amount.saturating_add(min_balance);
let refund = amount.saturating_sub(min_balance);
if refund > NearToken::from_near(0) {
Promise::new(env::predecessor_account_id()).transfer(refund);
}
Expand Down

0 comments on commit b074fc8

Please sign in to comment.