-
Notifications
You must be signed in to change notification settings - Fork 1
/
lib.rs
259 lines (212 loc) · 7.83 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
use near_sdk::PromiseError;
use std::collections::HashMap;
use std::convert::Into;
use std::convert::TryInto;
use std::fmt;
use uint::construct_uint;
use near_contract_standards::storage_management::{
StorageBalance, StorageBalanceBounds, StorageManagement,
};
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::collections::{LookupMap, UnorderedSet};
use near_sdk::json_types::U128;
use near_sdk::serde::{Deserialize, Serialize};
use near_sdk::{
assert_one_yocto, env, ext_contract, log, near_bindgen, require, AccountId, Balance,
BorshStorageKey, Gas, PanicOnDefault, Promise, PromiseOrValue, PromiseResult,
};
use percentage::Percentage;
use crate::account_deposit::{Account, VAccount};
mod account_deposit;
mod storage_impl;
mod token_receiver;
mod external_contracts;
pub use external_contracts::*;
pub mod utils;
use utils::*;
mod errors;
use crate::errors::*;
mod ref_finance;
use ref_finance::*;
mod jumbo;
use crate::jumbo::*;
mod pembrock;
use pembrock::*;
mod views;
mod fluxus_strat;
use fluxus_strat::*;
mod actions_of_strat;
mod owner;
pub mod admin_fee;
pub use admin_fee::*;
pub mod callback;
use callback::*;
mod multi_fungible_token;
#[derive(BorshStorageKey, BorshSerialize)]
pub(crate) enum StorageKey {
Accounts,
Whitelist,
AccountTokens { account_id: AccountId },
Guardian,
NearDeposited,
UsersBalanceByShare,
TotalSupplyByShare,
SeedIdAmount,
SeedRegister { fft_share: String },
Strategy { fft_share_id: String },
}
// TODO: update this to newer version, following AutoCompounderState
#[derive(Debug, BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Clone)]
#[serde(crate = "near_sdk::serde")]
pub enum RunningState {
Running,
Paused,
}
impl fmt::Display for RunningState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
RunningState::Running => write!(f, "Running"),
RunningState::Paused => write!(f, "Paused"),
}
}
}
// TODO: update to a versionable contract
#[near_bindgen]
#[derive(BorshSerialize, BorshDeserialize, PanicOnDefault)]
pub struct ContractData {
// Account address that have authority to update the contract state
owner_id: AccountId,
/// Set of guardians.
guardians: UnorderedSet<AccountId>,
/// Fees earned by the DAO
treasury: AccountFee,
// Keeps tracks of accounts that send coins to this contract
accounts: LookupMap<AccountId, VAccount>,
// Keeps track of address that have permission to call auto-compound related methods
allowed_accounts: Vec<AccountId>,
// Keeps track of tokens that the contracts can receive
whitelisted_tokens: UnorderedSet<AccountId>,
// State is used to update the contract to a Paused/Running state
state: RunningState,
// Used by storage_impl and account_deposit to keep track of NEAR deposit in this contract
users_total_near_deposited: LookupMap<AccountId, u128>,
///It is a map that store the fft_share and a map of users and their balance.
/// illustration: map(fft_share[i], map(user[i], balance[i])).
users_balance_by_fft_share: LookupMap<String, LookupMap<String, u128>>,
///Store the fft_share total_supply for each seed_id.
total_supply_by_fft_share: LookupMap<String, u128>,
///Store the fft_share for each seed_id.
/// TODO: Change HashMap for LookupMap as it is more gas efficient
fft_share_by_seed_id: HashMap<String, String>,
///Store the fft_share for each seed_id.
seed_id_amount: LookupMap<String, u128>,
// Keeps track of token_id to strategy used
strategies: HashMap<String, VersionedStrategy>,
}
construct_uint! {
/// 256-bit unsigned integer.
pub struct U256(4);
}
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)]
pub struct Contract {
data: VersionedContractData,
}
/// Versioned contract data. Allows to easily upgrade contracts.
#[derive(BorshSerialize, BorshDeserialize)]
pub enum VersionedContractData {
V0001(ContractData),
}
impl VersionedContractData {}
#[near_bindgen]
impl Contract {
#[init]
pub fn new(owner_id: AccountId, treasure_contract_id: AccountId) -> Self {
assert!(!env::state_exists(), "Already initialized");
let allowed_accounts: Vec<AccountId> = vec![env::current_account_id()];
let treasury: AccountFee = AccountFee {
account_id: treasure_contract_id,
fee_percentage: 10, //TODO: the treasury fee_percentage can be removed from here as the treasury contract will receive all the fees amount that won't be sent to strat_creator or sentry
// The breakdown of amount for Stakers, operations and treasury will be dealt with inside the treasury contract
current_amount: 0u128,
};
Self {
data: VersionedContractData::V0001(ContractData {
owner_id,
guardians: UnorderedSet::new(StorageKey::Guardian),
treasury,
accounts: LookupMap::new(StorageKey::Accounts),
allowed_accounts,
whitelisted_tokens: UnorderedSet::new(StorageKey::Whitelist),
state: RunningState::Running,
users_total_near_deposited: LookupMap::new(StorageKey::NearDeposited),
users_balance_by_fft_share: LookupMap::new(StorageKey::UsersBalanceByShare),
total_supply_by_fft_share: LookupMap::new(StorageKey::TotalSupplyByShare),
fft_share_by_seed_id: HashMap::new(),
seed_id_amount: LookupMap::new(StorageKey::SeedIdAmount),
/// List of all the pools.
/// TODO: with more exchanges, this should not exist
strategies: HashMap::new(),
}),
}
}
}
impl Contract {
#[allow(unreachable_patterns)]
fn data(&self) -> &ContractData {
match &self.data {
VersionedContractData::V0001(data) => data,
_ => unimplemented!(),
}
}
#[allow(unreachable_patterns)]
fn data_mut(&mut self) -> &mut ContractData {
match &mut self.data {
VersionedContractData::V0001(data) => data,
_ => unimplemented!(),
}
}
fn assert_contract_running(&self) {
match self.data().state {
RunningState::Running => (),
_ => env::panic_str("E51: contract paused"),
};
}
/// Ensures that at least one strategy is running for given token_id
fn assert_strategy_is_running(&self, seed_id: &str) {
let strat = self.get_strat(seed_id);
match strat {
VersionedStrategy::AutoCompounder(_) => {
let compounder = strat.get_compounder_ref();
for farm in compounder.farms.iter() {
if farm.state == AutoCompounderState::Running {
return;
}
}
}
VersionedStrategy::StableAutoCompounder(_) => {
let compounder = strat.get_stable_compounder_ref();
for farm in compounder.farms.iter() {
if farm.state == AutoCompounderState::Running {
return;
}
}
}
VersionedStrategy::JumboAutoCompounder(_) => {
let compounder = strat.get_jumbo();
for farm in compounder.farms.iter() {
if farm.state == JumboAutoCompounderState::Running {
return;
}
}
}
VersionedStrategy::PembrockAutoCompounder(_) => {
let compounder = strat.pemb_get_ref();
if compounder.state == PembAutoCompounderState::Running {
return;
}
}
}
panic!("There is no running strategy for this pool")
}
}