Skip to content

Commit

Permalink
Add sfrax (#103)
Browse files Browse the repository at this point in the history
* skip_unwrap_near

* update makefile

* build release

* add auto_whitelisted_postfix

* add sfrax

* add SfraxExtraInfo check

* update value

---------

Co-authored-by: Marco <[email protected]>
  • Loading branch information
MagicGordon and Marco authored Apr 5, 2024
1 parent 5f6ec6d commit 5fd4997
Show file tree
Hide file tree
Showing 22 changed files with 1,326 additions and 108 deletions.
22 changes: 21 additions & 1 deletion Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ members = [
"./ref-farming",
"./test-rated-token",
"./mock-boost-farming",
"./mock-wnear"
"./mock-price-oracle",
"./mock-wnear",
"./mock-pyth"
]


Expand Down
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@ else
RUSTFLAGS=$(RFLAGS) cargo test -p ref-exchange --lib -- --nocapture
endif

test: build-exchange mock-ft mock-rated mock-farming test-wnear
test: build-exchange mock-ft mock-rated mock-farming test-wnear test-price-oracle test-pyth
ifdef TF
RUSTFLAGS=$(RFLAGS) cargo test -p ref-exchange --test $(TF) -- --nocapture
else
RUSTFLAGS=$(RFLAGS) cargo test -p ref-exchange --tests
endif

test-exchange: build-exchange mock-ft mock-rated mock-farming test-wnear
test-exchange: build-exchange mock-ft mock-rated mock-farming test-wnear test-price-oracle test-pyth
RUSTFLAGS=$(RFLAGS) cargo test -p ref-exchange

test-farm: build-farm mock-ft
RUSTFLAGS=$(RFLAGS) cargo test -p ref_farming

test-release: mock-ft mock-rated mock-farming test-wnear
test-release: mock-ft mock-rated mock-farming test-wnear test-price-oracle test-pyth
mkdir -p res
cp ./releases/ref_exchange_release.wasm ./res/ref_exchange.wasm
RUSTFLAGS=$(RFLAGS) cargo test -p ref-exchange
Expand Down Expand Up @@ -62,6 +62,18 @@ test-wnear: mock-wnear
RUSTFLAGS=$(RFLAGS) cargo build -p mock-wnear --target wasm32-unknown-unknown --release
mkdir -p res
cp target/wasm32-unknown-unknown/release/mock_wnear.wasm ./res/mock_wnear.wasm

test-price-oracle: mock-price-oracle
rustup target add wasm32-unknown-unknown
RUSTFLAGS=$(RFLAGS) cargo build -p mock-price-oracle --target wasm32-unknown-unknown --release
mkdir -p res
cp target/wasm32-unknown-unknown/release/mock_price_oracle.wasm ./res/mock_price_oracle.wasm

test-pyth: mock-pyth
rustup target add wasm32-unknown-unknown
RUSTFLAGS=$(RFLAGS) cargo build -p mock-pyth --target wasm32-unknown-unknown --release
mkdir -p res
cp target/wasm32-unknown-unknown/release/mock_pyth.wasm ./res/mock_pyth.wasm

release:
$(call docker_build,_rust_setup.sh)
Expand Down
13 changes: 13 additions & 0 deletions mock-price-oracle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "mock-price-oracle"
version = "0.1.0"
edition = "2018"
publish = false

[lib]
crate-type = ["cdylib", "rlib"]


[dependencies]
near-sdk = "3.1.0"
near-contract-standards = "3.1.0"
123 changes: 123 additions & 0 deletions mock-price-oracle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
use std::collections::HashMap;

use near_sdk::serde::{Deserialize, Serialize};
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::{near_bindgen, PanicOnDefault};
use near_sdk::{env, Balance, Timestamp};

type AssetId = String;

#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, Clone)]
#[serde(crate = "near_sdk::serde")]
pub struct Price {
#[serde(with = "u128_dec_format")]
pub multiplier: Balance,
pub decimals: u8,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(crate = "near_sdk::serde")]
pub struct AssetOptionalPrice {
pub asset_id: AssetId,
pub price: Option<Price>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(crate = "near_sdk::serde")]
pub struct PriceData {
#[serde(with = "u64_dec_format")]
pub timestamp: Timestamp,
pub recency_duration_sec: u32,

pub prices: Vec<AssetOptionalPrice>,
}

#[near_bindgen]
#[derive(BorshSerialize, BorshDeserialize, PanicOnDefault)]
pub struct Contract {
prices: HashMap<AssetId, Price>
}

#[near_bindgen]
impl Contract {
#[init]
pub fn new() -> Self {
Self {
prices: HashMap::new(),
}
}

pub fn set_price_data(&mut self, asset_id: AssetId, price: Price) {
self.prices.insert(asset_id, price);
}

pub fn get_price_data(&self, asset_ids: Option<Vec<AssetId>>) -> PriceData {
// let asset_ids = asset_ids.unwrap_or(vec![]);
PriceData {
timestamp: env::block_timestamp(),
recency_duration_sec: 90,
prices: {
let mut res = vec![];
if let Some(asset_ids) = asset_ids {
for asset_id in asset_ids {
res.push(AssetOptionalPrice{
asset_id: asset_id.clone(),
price: self.prices.get(&asset_id).cloned(),
});
}
} else {
for (asset_id, price) in self.prices.iter() {
res.push(AssetOptionalPrice{
asset_id: asset_id.clone(),
price: Some(price.clone()),
});
}
}
res
}
}
}

}

pub(crate) mod u128_dec_format {
use near_sdk::serde::de;
use near_sdk::serde::{Deserialize, Deserializer, Serializer};

pub fn serialize<S>(num: &u128, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&num.to_string())
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<u128, D::Error>
where
D: Deserializer<'de>,
{
String::deserialize(deserializer)?
.parse()
.map_err(de::Error::custom)
}
}

pub(crate) mod u64_dec_format {
use near_sdk::serde::de;
use near_sdk::serde::{Deserialize, Deserializer, Serializer};

pub fn serialize<S>(num: &u64, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&num.to_string())
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{
String::deserialize(deserializer)?
.parse()
.map_err(de::Error::custom)
}
}
13 changes: 13 additions & 0 deletions mock-pyth/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "mock-pyth"
version = "0.1.0"
edition = "2018"
publish = false

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
near-sdk = "3.1.0"
near-contract-standards = "3.1.0"
hex = "0.4.3"
98 changes: 98 additions & 0 deletions mock-pyth/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use std::collections::HashMap;

use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::json_types::{I64, U64};
use near_sdk::serde::{Deserialize, Serialize};
use near_sdk::{near_bindgen, PanicOnDefault};

#[derive(BorshDeserialize, BorshSerialize, Debug, Deserialize, Serialize, Clone)]
#[serde(crate = "near_sdk::serde")]
pub struct PythPrice {
pub price: I64,
/// Confidence interval around the price
pub conf: U64,
/// The exponent
pub expo: i32,
/// Unix timestamp of when this price was computed
pub publish_time: i64,
}

#[derive(BorshDeserialize, BorshSerialize, PartialOrd, PartialEq, Eq, Hash, Clone)]
#[repr(transparent)]
pub struct PriceIdentifier(pub [u8; 32]);

impl<'de> near_sdk::serde::Deserialize<'de> for PriceIdentifier {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: near_sdk::serde::Deserializer<'de>,
{
/// A visitor that deserializes a hex string into a 32 byte array.
struct IdentifierVisitor;

impl<'de> near_sdk::serde::de::Visitor<'de> for IdentifierVisitor {
/// Target type for either a hex string or a 32 byte array.
type Value = [u8; 32];

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a hex string")
}

// When given a string, attempt a standard hex decode.
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: near_sdk::serde::de::Error,
{
if value.len() != 64 {
return Err(E::custom(format!(
"expected a 64 character hex string, got {}",
value.len()
)));
}
let mut bytes = [0u8; 32];
hex::decode_to_slice(value, &mut bytes).map_err(E::custom)?;
Ok(bytes)
}
}

deserializer
.deserialize_any(IdentifierVisitor)
.map(PriceIdentifier)
}
}

impl near_sdk::serde::Serialize for PriceIdentifier {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: near_sdk::serde::Serializer,
{
serializer.serialize_str(&hex::encode(&self.0))
}
}

#[near_bindgen]
#[derive(BorshSerialize, BorshDeserialize, PanicOnDefault)]
pub struct Contract {
price_info: HashMap<PriceIdentifier, PythPrice>,
}

#[near_bindgen]
impl Contract {
#[init]
pub fn new() -> Self {
Self {
price_info: HashMap::new()
}
}

pub fn set_price(&mut self, price_identifier: PriceIdentifier, pyth_price: PythPrice) {
self.price_info.insert(price_identifier, pyth_price);
}

pub fn remove_price(&mut self, price_identifier: PriceIdentifier) {
self.price_info.remove(&price_identifier);
}

pub fn get_price(&self, price_identifier: PriceIdentifier) -> Option<PythPrice> {
self.price_info.get(&price_identifier).cloned()
}
}
5 changes: 4 additions & 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.0"
version = "1.9.1"
authors = ["Illia Polosukhin <[email protected]>"]
edition = "2018"
publish = false
Expand All @@ -13,12 +13,15 @@ uint = { version = "0.9.3", default-features = false }
near-sdk = "3.1.0"
near-contract-standards = "3.1.0"
once_cell = "=1.8.0"
hex = "0.4.3"

[dev-dependencies]
near-sdk-sim = "3.1.0"
test-token = { path = "../test-token" }
test-rated-token = { path = "../test-rated-token" }
mock-boost-farming = { path = "../mock-boost-farming" }
mock-wnear = { path = "../mock-wnear" }
mock-price-oracle = { path = "../mock-price-oracle" }
mock-pyth = { path = "../mock-pyth" }
rand = "0.8"
rand_pcg = "0.3"
3 changes: 2 additions & 1 deletion ref-exchange/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,12 @@ pub const ERR110_INVALID_REGISTER: &str = "E110: Invalid register";
// rated pool
pub const ERR120_RATES_EXPIRED: &str = "E120: Rates expired";
// pub const ERR122_FAILED_TO_UPDATE_RATES: &str = "E122: Failed to update rates";
pub const ERR123_ONE_PROMISE_RESULT: &str = "E123: Cross-contract call should have exactly one promise result";
pub const ERR123_TWO_PROMISE_RESULT: &str = "E123: Cross-contract call should have exactly two promise result";
pub const ERR124_CROSS_CALL_FAILED: &str = "E124: Cross-contract call failed";
// pub const ERR125_FAILED_TO_APPLY_RATES: &str = "E125: Failed to apply new rates";
pub const ERR126_FAILED_TO_PARSE_RESULT: &str = "E126: Failed to parse cross-contract call result";
pub const ERR127_INVALID_RATE_TYPE: &str = "E127: Invalid rate type";
pub const ERR128_INVALID_EXTRA_INFO_MSG_FORMAT: &str = "E128: Invalid extra info message format";

// referrals
pub const ERR130_REFERRAL_EXIST: &str = "E130: Referral already exist";
Expand Down
Loading

0 comments on commit 5fd4997

Please sign in to comment.