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

xCheddar impl #14

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
# "./p1-staking-pool-dyn",
"./p2-token-staking-fixed",
"./p3-farm",
"./xcheddar"
]


Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ Cheddar Network is the leading ecosystem for NEAR dapps. Our mission is to be gr
## Cheddar Defi Farm

A Defi token and farm on NEAR. Cheddar is a fun way for NEAR users to collect, swap and send Cheddar. To get Cheddar you can swap NEAR and stake it in the farm to stack even more Cheddar. Cheddar will also include a DAO (Phase II) where users can lock Cheddar to receive governance tokens to participate in the development process while earning additional rewards.

## XCheddar token

Token which allows users stake their Cheddar tokens and get some rewards for it. Base model is the same as CRV and veCRV locked tokens model. After 30-days period distribution of rewards starts and it counting from monthly reward parameter. Locked token have a virtual price depends on amount of locked/minted XCheddar tokens
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you add a links to CRV and veCRV?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@robert-zaremba yep, what’s required? I update all with ahead commits

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

links to explain CRV and veCRV

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 changes: 4 additions & 4 deletions cheddar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
serde = { version = "*", features = ["derive"] }
serde_json = "*"
near-sdk = { git = "https://github.com/near/near-sdk-rs", tag="3.1.0" }
near-contract-standards = { git = "https://github.com/near/near-sdk-rs", tag="3.1.0" }
near-sdk = "4.0.0-pre.7"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
near-sdk = "4.0.0-pre.7"
near-sdk = "4.0.0"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v4 is already released, let's don't use -pre

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can already use v4.1.0-pre

near-sys = "0.1.0"
near-contract-standards = "4.0.0-pre.7"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
near-contract-standards = "4.0.0-pre.7"
near-contract-standards = "4.0.0"

uint = { version = "0.9.0", default-features = false }

[dev-dependencies]
# near-primitives = { git = "https://github.com/nearprotocol/nearcore.git" }
# near-sdk-sim = { git = "https://github.com/near/near-sdk-rs.git", version="v3.1.0" }
near-sdk-sim = "4.0.0-pre.7"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
near-sdk-sim = "4.0.0-pre.7"
near-sdk-sim = "4.0.0"

11 changes: 11 additions & 0 deletions cheddar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,14 @@ Main features of Cheddar Coin are:
## Technicalities

The Cheddar Coin implements the `NEP-141` standard. It's a fungible token.


### Compiling

You can build release version by running next scripts inside each contract folder:

```
rustup target add wasm32-unknown-unknown
RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release
cp target/wasm32-unknown-unknown/release/cheddar_coin.wasm /Users/macbookpro/Documents/GitHub/xCheddar-token/xCheddar/res/cheddar_coin.wasm
robert-zaremba marked this conversation as resolved.
Show resolved Hide resolved
```
8 changes: 4 additions & 4 deletions cheddar/src/internal.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use near_sdk::json_types::{ValidAccountId, U128};
use near_sdk::json_types::U128;
use near_sdk::{AccountId, Balance, PromiseResult};

use crate::storage::AccBalance;
Expand All @@ -13,7 +13,7 @@ impl Contract {
}

#[inline]
pub(crate) fn assert_minter(&self, account_id: String) {
pub(crate) fn assert_minter(&self, account_id: AccountId) {
assert!(self.minters.contains(&account_id), "not a minter");
}

Expand Down Expand Up @@ -123,10 +123,10 @@ impl Contract {
pub(crate) fn ft_resolve_transfer_adjust(
&mut self,
sender_id: &AccountId,
receiver_id: ValidAccountId,
receiver_id: AccountId,
amount: U128,
) -> (u128, u128) {
let receiver_id: AccountId = receiver_id.into();

let amount: Balance = amount.into();

// Get the unused amount from the `ft_on_transfer` call result.
Expand Down
46 changes: 21 additions & 25 deletions cheddar/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/// Cheddar Token
///
/// Functionality:
/// - No account storage complexity - Since NEAR slashed storage price by 10x
/// it does not make sense to add that friction (storage backup per user).
Expand All @@ -16,19 +15,11 @@ use near_contract_standards::fungible_token::{
};
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::collections::{LazyOption, LookupMap};
use near_sdk::json_types::{ValidAccountId, U128};
use near_sdk::json_types::U128;
use near_sdk::{
assert_one_yocto, env, ext_contract, log, near_bindgen, AccountId, Balance, Gas,
assert_one_yocto, env, ext_contract, log, near_bindgen, AccountId, Balance,
PanicOnDefault, PromiseOrValue,
};

const TGAS: Gas = 1_000_000_000_000;
const GAS_FOR_RESOLVE_TRANSFER: Gas = 5 * TGAS;
const GAS_FOR_FT_TRANSFER_CALL: Gas = 25 * TGAS + GAS_FOR_RESOLVE_TRANSFER;
const NO_DEPOSIT: Balance = 0;

near_sdk::setup_alloc!();

mod internal;
mod migrations;
mod storage;
Expand Down Expand Up @@ -165,9 +156,14 @@ impl Contract {
self.metadata.set(&m);
}

pub fn set_owner(&mut self, owner_id: ValidAccountId) {
pub fn set_owner(&mut self, owner_id: AccountId) {
self.assert_owner();
self.owner_id = owner_id.as_ref().clone();
assert!(
env::is_valid_account_id(owner_id.as_bytes()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need to validate, AccountId should be validated automatically

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFIAK, v4 validates account automatically

"Account @{} is invalid!",
owner_id.clone()
);
self.owner_id = owner_id.clone();
}

/// Get the owner of this account.
Expand Down Expand Up @@ -240,40 +236,40 @@ impl Contract {
#[near_bindgen]
impl FungibleTokenCore for Contract {
#[payable]
fn ft_transfer(&mut self, receiver_id: ValidAccountId, amount: U128, memo: Option<String>) {
fn ft_transfer(&mut self, receiver_id: AccountId, amount: U128, memo: Option<String>) {
robert-zaremba marked this conversation as resolved.
Show resolved Hide resolved
assert_one_yocto();
let sender_id = env::predecessor_account_id();
let amount: Balance = amount.into();
self.internal_transfer(&sender_id, receiver_id.as_ref(), amount, memo);
self.internal_transfer(&sender_id, &receiver_id, amount, memo);
}

#[payable]
fn ft_transfer_call(
&mut self,
receiver_id: ValidAccountId,
receiver_id: AccountId,
amount: U128,
memo: Option<String>,
msg: String,
) -> PromiseOrValue<U128> {
assert_one_yocto();
let sender_id = env::predecessor_account_id();
let amount: Balance = amount.into();
self.internal_transfer(&sender_id, receiver_id.as_ref(), amount, memo);
self.internal_transfer(&sender_id, &receiver_id, amount, memo);
// Initiating receiver's call and the callback
// ext_fungible_token_receiver::ft_on_transfer(
ext_ft_receiver::ft_on_transfer(
sender_id.clone(),
amount.into(),
msg,
receiver_id.as_ref(),
receiver_id.clone(),
NO_DEPOSIT,
env::prepaid_gas() - GAS_FOR_FT_TRANSFER_CALL,
)
.then(ext_self::ft_resolve_transfer(
sender_id,
receiver_id.into(),
receiver_id,
amount.into(),
&env::current_account_id(),
env::current_account_id(),
NO_DEPOSIT,
GAS_FOR_RESOLVE_TRANSFER,
))
Expand All @@ -284,8 +280,8 @@ impl FungibleTokenCore for Contract {
self.total_supply.into()
}

fn ft_balance_of(&self, account_id: ValidAccountId) -> U128 {
self._balance_of(account_id.as_ref()).into()
fn ft_balance_of(&self, account_id: AccountId) -> U128 {
self._balance_of(&account_id).into()
}
}

Expand All @@ -297,8 +293,8 @@ impl FungibleTokenResolver for Contract {
#[private]
fn ft_resolve_transfer(
&mut self,
sender_id: ValidAccountId,
receiver_id: ValidAccountId,
sender_id: AccountId,
receiver_id: AccountId,
amount: U128,
) -> U128 {
let sender_id: AccountId = sender_id.into();
Expand Down Expand Up @@ -347,7 +343,7 @@ mod tests {

const OWNER_SUPPLY: Balance = 1_000_000_000_000_000_000_000_000_000_000;

fn get_context(predecessor_account_id: ValidAccountId) -> VMContextBuilder {
fn get_context(predecessor_account_id: AccountId) -> VMContextBuilder {
let mut builder = VMContextBuilder::new();
builder
.current_account_id(accounts(0))
Expand Down
24 changes: 11 additions & 13 deletions cheddar/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use near_contract_standards::storage_management::{
StorageBalance, StorageBalanceBounds, StorageManagement,
};
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::json_types::{ValidAccountId, U128};
use near_sdk::json_types::U128;
use near_sdk::{assert_one_yocto, env, log, near_bindgen, AccountId, Balance, Promise};

// The storage size in bytes for one account.
Expand Down Expand Up @@ -32,7 +32,7 @@ impl Contract {
)
.is_some()
{
env::panic("The account is already registered".as_bytes());
panic!("The account is already registered");
}
}

Expand Down Expand Up @@ -70,10 +70,7 @@ impl Contract {
}
Some((account_id, balance.near))
} else {
env::panic(
"Can't unregister the account with the positive balance without force"
.as_bytes(),
)
panic!("Can't unregister the account with the positive balance without force")
}
} else {
log!("The account {} is not registered", &account_id);
Expand All @@ -94,7 +91,7 @@ impl StorageManagement for Contract {
#[payable]
fn storage_deposit(
&mut self,
account_id: Option<ValidAccountId>,
account_id: Option<AccountId>,
registration_only: Option<bool>,
) -> StorageBalance {
let amount: Balance = env::attached_deposit();
Expand Down Expand Up @@ -137,15 +134,16 @@ impl StorageManagement for Contract {
if self.accounts.contains_key(&predecessor_account_id) {
match amount {
Some(amount) if amount.0 > 0 => {
env::panic(
"The amount is greater than the available storage balance".as_bytes(),
panic!(
"The amount is greater than the available storage balance",
);
}
_ => storage_balance(),
}
} else {
env::panic(
format!("The account {} is not registered", &predecessor_account_id).as_bytes(),
panic!(
"The account {} is not registered",
predecessor_account_id
);
}
}
Expand All @@ -162,8 +160,8 @@ impl StorageManagement for Contract {
}
}

fn storage_balance_of(&self, account_id: ValidAccountId) -> Option<StorageBalance> {
if self.accounts.contains_key(account_id.as_ref()) {
fn storage_balance_of(&self, account_id: AccountId) -> Option<StorageBalance> {
if self.accounts.contains_key(&account_id) {
Some(storage_balance())
} else {
None
Expand Down
81 changes: 37 additions & 44 deletions cheddar/src/upgrade.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,52 @@
//! Implement all the relevant logic for smart contract upgrade.

use crate::*;

#[cfg(target_arch = "wasm32")]
mod upgrade {
use near_sdk::env::BLOCKCHAIN_INTERFACE;
use near_sdk::env;
use near_sdk::Gas;
use crate::Contract;
use near_sys as sys;

use super::*;

const BLOCKCHAIN_INTERFACE_NOT_SET_ERR: &str = "Blockchain interface not set.";

/// Gas for calling migration call.
pub const GAS_FOR_MIGRATE_CALL: Gas = 5_000_000_000_000;
use crate::util::*;

/// Self upgrade and call migrate, optimizes gas by not loading into memory the code.
/// Takes as input non serialized set of bytes of the code.
/// After upgrade we call *pub fn migrate()* on the NEW CONTRACT CODE
#[no_mangle]
pub extern "C" fn upgrade() {
pub fn upgrade() {
/// Gas for calling migration call. One Tera - 1 TGas
/// 20 Tgas
pub const GAS_FOR_UPGRADE: Gas = Gas(20_000_000_000_000);
const BLOCKCHAIN_INTERFACE_NOT_SET_ERR: &str = "Blockchain interface not set.";

env::setup_panic_hook();
env::set_blockchain_interface(Box::new(near_blockchain::NearBlockchain {}));

///assert ownership
#[allow(unused_doc_comments)]
let contract: Contract = env::state_read().expect("ERR_CONTRACT_IS_NOT_INITIALIZED");
contract.assert_owner();
let current_id = env::current_account_id().into_bytes();
let method_name = "migrate".as_bytes().to_vec();

let current_id = env::current_account_id();
let migrate_method_name = "migrate".as_bytes().to_vec();
let attached_gas = env::prepaid_gas() - env::used_gas() - GAS_FOR_UPGRADE;
unsafe {
BLOCKCHAIN_INTERFACE.with(|b| {
// Load input into register 0.
b.borrow()
.as_ref()
.expect(BLOCKCHAIN_INTERFACE_NOT_SET_ERR)
.input(0);
let promise_id = b
.borrow()
.as_ref()
.expect(BLOCKCHAIN_INTERFACE_NOT_SET_ERR)
.promise_batch_create(current_id.len() as _, current_id.as_ptr() as _);
b.borrow()
.as_ref()
.expect(BLOCKCHAIN_INTERFACE_NOT_SET_ERR)
.promise_batch_action_deploy_contract(promise_id, u64::MAX as _, 0);
let attached_gas = env::prepaid_gas() - env::used_gas() - GAS_FOR_MIGRATE_CALL;
b.borrow()
.as_ref()
.expect(BLOCKCHAIN_INTERFACE_NOT_SET_ERR)
.promise_batch_action_function_call(
promise_id,
method_name.len() as _,
method_name.as_ptr() as _,
0 as _,
0 as _,
0 as _,
attached_gas,
);
});
// Load input (NEW CONTRACT CODE) into register 0.
sys::input(0);
// prepare self-call promise
let promise_id = sys::promise_batch_create(current_id.as_bytes().len() as _, current_id.as_bytes().as_ptr() as _);

// #Action_1 - deploy/upgrade code from register 0
sys::promise_batch_action_deploy_contract(promise_id, u64::MAX as _, 0);
// #Action_2 - schedule a call for migrate
// Execute on NEW CONTRACT CODE
sys::promise_batch_action_function_call(
promise_id,
migrate_method_name.len() as _,
migrate_method_name.as_ptr() as _,
0 as _,
0 as _,
0 as _,
u64::from(attached_gas),
);
robert-zaremba marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
10 changes: 10 additions & 0 deletions cheddar/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
use near_sdk::json_types::{U128, U64};
use near_sdk::{Balance, Gas};
use uint::construct_uint;

pub type U128String = U128;
pub type U64String = U64;

/// One Tera gas (Tgas), which is 10^12 gas units.
#[allow(dead_code)]
pub const ONE_TERA: Gas = Gas(1_000_000_000_000);
/// 5 Tgas
pub const GAS_FOR_RESOLVE_TRANSFER: Gas = Gas(5_000_000_000_000);
/// 30 Tgas (25 Tgas + GAS_FOR_RESOLVE_TRANSFER)
pub const GAS_FOR_FT_TRANSFER_CALL: Gas = Gas(30_000_000_000_000);
pub const NO_DEPOSIT: Balance = 0;

construct_uint! {
/// 256-bit unsigned integer.
pub struct U256(4);
Expand Down
1 change: 1 addition & 0 deletions neardev/dev-account
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dev-1654515440352-14631167054094
1 change: 1 addition & 0 deletions neardev/dev-account.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONTRACT_NAME=dev-1654515440352-14631167054094
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add neardev to .gitignore

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do

Loading