Skip to content

Commit aa2d617

Browse files
committed
Alligned with master
2 parents ef89e10 + ef793f8 commit aa2d617

File tree

6 files changed

+237
-3
lines changed

6 files changed

+237
-3
lines changed

resources/invariant_schema.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,64 @@
123123
"List": "Any"
124124
}
125125
},
126+
{
127+
"name": "get_protocol_fee",
128+
"is_mutable": false,
129+
"args": [],
130+
"return_ty": "Any"
131+
},
132+
{
133+
"name": "withdraw_protocol_fee",
134+
"is_mutable": true,
135+
"args": [
136+
{
137+
"name": "pool_key",
138+
"ty": "Any"
139+
}
140+
],
141+
"return_ty": {
142+
"Result": {
143+
"ok": "Unit",
144+
"err": "U32"
145+
}
146+
}
147+
},
148+
{
149+
"name": "change_protocol_fee",
150+
"is_mutable": true,
151+
"args": [
152+
{
153+
"name": "protocol_fee",
154+
"ty": "Any"
155+
}
156+
],
157+
"return_ty": {
158+
"Result": {
159+
"ok": "Unit",
160+
"err": "U32"
161+
}
162+
}
163+
},
164+
{
165+
"name": "change_fee_receiver",
166+
"is_mutable": true,
167+
"args": [
168+
{
169+
"name": "pool_key",
170+
"ty": "Any"
171+
},
172+
{
173+
"name": "fee_receiver",
174+
"ty": "Key"
175+
}
176+
],
177+
"return_ty": {
178+
"Result": {
179+
"ok": "Unit",
180+
"err": "U32"
181+
}
182+
}
183+
},
126184
{
127185
"name": "is_tick_initialized",
128186
"is_mutable": false,

src/contracts/entrypoints.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use super::{FeeTier, Pool, PoolKey, Position, Tick};
22
use crate::{
3-
math::{liquidity::Liquidity, sqrt_price::SqrtPrice, token_amount::TokenAmount},
3+
math::{
4+
liquidity::Liquidity, percentage::Percentage, sqrt_price::SqrtPrice,
5+
token_amount::TokenAmount,
6+
},
47
InvariantError,
58
};
69
use odra::{prelude::vec::Vec, types::Address};
@@ -26,8 +29,16 @@ pub trait Entrypoints {
2629
) -> Result<Pool, InvariantError>;
2730
fn get_pools(&self) -> Vec<PoolKey>;
2831

29-
fn is_tick_initialized(&self, key: PoolKey, index: i32) -> bool;
32+
fn get_protocol_fee(&self) -> Percentage;
33+
fn withdraw_protocol_fee(&mut self, pool_key: PoolKey) -> Result<(), InvariantError>;
34+
fn change_protocol_fee(&mut self, protocol_fee: Percentage) -> Result<(), InvariantError>;
35+
fn change_fee_receiver(
36+
&mut self,
37+
pool_key: PoolKey,
38+
fee_receiver: Address,
39+
) -> Result<(), InvariantError>;
3040

41+
fn is_tick_initialized(&self, key: PoolKey, index: i32) -> bool;
3142
fn get_tick(&self, key: PoolKey, index: i32) -> Result<Tick, InvariantError>;
3243

3344
fn claim_fee(&mut self, index: u32) -> Result<(TokenAmount, TokenAmount), InvariantError>;

src/e2e/change_fee_receiver.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::math::percentage::Percentage;
2+
use crate::InvariantDeployer;
3+
use crate::InvariantError;
4+
use crate::{FeeTier, PoolKey};
5+
use decimal::*;
6+
use odra::test_env;
7+
use odra::types::casper_types::ContractPackageHash;
8+
use odra::types::Address;
9+
use odra::types::U128;
10+
11+
#[test]
12+
fn test_change_fee_reciever() {
13+
let token_0 = Address::Contract(ContractPackageHash::from([0x01; 32]));
14+
let token_1 = Address::Contract(ContractPackageHash::from([0x02; 32]));
15+
16+
let deployer = test_env::get_account(0);
17+
test_env::set_caller(deployer);
18+
let mut invariant = InvariantDeployer::init(Percentage::new(U128::from(0)));
19+
20+
let fee_tier = FeeTier::new(Percentage::from_scale(5, 1), 1).unwrap();
21+
invariant.add_fee_tier(fee_tier).unwrap();
22+
23+
let exist = invariant.fee_tier_exist(fee_tier);
24+
assert!(exist);
25+
26+
let init_tick = 0;
27+
invariant
28+
.create_pool(token_0, token_1, fee_tier, init_tick)
29+
.unwrap();
30+
31+
let new_receiver = test_env::get_account(1);
32+
let pool_key = PoolKey::new(token_0, token_1, fee_tier).unwrap();
33+
34+
invariant
35+
.change_fee_receiver(pool_key, new_receiver)
36+
.unwrap();
37+
38+
let pool = invariant.get_pool(token_0, token_1, fee_tier).unwrap();
39+
assert_eq!(pool.fee_receiver, new_receiver);
40+
}
41+
42+
#[test]
43+
fn test_not_admin_change_fee_reciever() {
44+
let token_0 = Address::Contract(ContractPackageHash::from([0x01; 32]));
45+
let token_1 = Address::Contract(ContractPackageHash::from([0x02; 32]));
46+
47+
let deployer = test_env::get_account(0);
48+
test_env::set_caller(deployer);
49+
let mut invariant = InvariantDeployer::init(Percentage::new(U128::from(0)));
50+
51+
let fee_tier = FeeTier::new(Percentage::from_scale(5, 1), 1).unwrap();
52+
invariant.add_fee_tier(fee_tier).unwrap();
53+
54+
let exist = invariant.fee_tier_exist(fee_tier);
55+
assert!(exist);
56+
57+
let init_tick = 0;
58+
invariant
59+
.create_pool(token_0, token_1, fee_tier, init_tick)
60+
.unwrap();
61+
62+
let new_receiver = test_env::get_account(1);
63+
let pool_key = PoolKey::new(token_0, token_1, fee_tier).unwrap();
64+
test_env::set_caller(new_receiver);
65+
let result = invariant.change_fee_receiver(pool_key, new_receiver);
66+
assert_eq!(result, Err(InvariantError::NotAdmin));
67+
}

src/e2e/change_protocol_fee.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use crate::math::percentage::Percentage;
2+
use crate::InvariantDeployer;
3+
use crate::InvariantError;
4+
use decimal::*;
5+
use odra::test_env;
6+
use odra::types::U128;
7+
8+
#[test]
9+
fn test_change_protocol_fee() {
10+
let deployer = test_env::get_account(0);
11+
test_env::set_caller(deployer);
12+
let mut invariant = InvariantDeployer::init(Percentage::new(U128::from(0)));
13+
14+
let protocol_fee = invariant.get_protocol_fee();
15+
assert_eq!(protocol_fee, Percentage::new(U128::from(0)));
16+
17+
let new_fee = Percentage::new(U128::from(1));
18+
invariant.change_protocol_fee(new_fee).unwrap();
19+
20+
let protocol_fee = invariant.get_protocol_fee();
21+
assert_eq!(protocol_fee, new_fee);
22+
}
23+
24+
#[test]
25+
fn test_change_protocol_fee_not_admin() {
26+
let deployer = test_env::get_account(0);
27+
test_env::set_caller(deployer);
28+
let mut invariant = InvariantDeployer::init(Percentage::new(U128::from(0)));
29+
30+
let protocol_fee = invariant.get_protocol_fee();
31+
assert_eq!(protocol_fee, Percentage::new(U128::from(0)));
32+
33+
let new_fee = Percentage::new(U128::from(1));
34+
test_env::set_caller(test_env::get_account(1));
35+
let result = invariant.change_protocol_fee(new_fee);
36+
37+
assert_eq!(result, Err(InvariantError::NotAdmin));
38+
}

src/e2e/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
pub mod add_fee_tier;
2+
pub mod change_fee_receiver;
3+
pub mod change_protocol_fee;
24
pub mod constructor;
35
pub mod create_pool;
46
pub mod remove_fee_tier;

src/lib.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ extern crate alloc;
55
pub mod contracts;
66
pub mod math;
77

8+
use odra_modules::erc20::Erc20Ref;
9+
810
#[cfg(test)]
911
pub mod e2e;
1012

@@ -21,7 +23,6 @@ use odra::types::event::OdraEvent;
2123
use odra::types::{Address, U256};
2224
use odra::{contract_env, Event};
2325
use odra::{OdraType, UnwrapOrRevert, Variable};
24-
use odra_modules::erc20::Erc20Ref;
2526

2627
#[derive(OdraType, Debug, PartialEq)]
2728
pub enum InvariantError {
@@ -267,6 +268,63 @@ impl Entrypoints for Invariant {
267268
self.pool_keys.get().unwrap_or_revert().get_all()
268269
}
269270

271+
pub fn get_protocol_fee(&self) -> Percentage {
272+
let state = self.state.get().unwrap_or_revert();
273+
state.protocol_fee
274+
}
275+
276+
pub fn withdraw_protocol_fee(&mut self, pool_key: PoolKey) -> Result<(), InvariantError> {
277+
let caller = contract_env::caller();
278+
let mut pool = self.pools.get(pool_key)?;
279+
280+
if caller != pool.fee_receiver {
281+
return Err(InvariantError::NotFeeReceiver);
282+
}
283+
284+
let (fee_protocol_token_x, fee_protocol_token_y) = pool.withdraw_protocol_fee(pool_key);
285+
286+
Erc20Ref::at(&pool_key.token_x).transfer(&pool.fee_receiver, &fee_protocol_token_x.get());
287+
Erc20Ref::at(&pool_key.token_y).transfer(&pool.fee_receiver, &fee_protocol_token_y.get());
288+
289+
self.pools.update(pool_key, &pool)?;
290+
291+
Ok(())
292+
}
293+
294+
pub fn change_protocol_fee(&mut self, protocol_fee: Percentage) -> Result<(), InvariantError> {
295+
let caller = contract_env::caller();
296+
let mut state = self.state.get().unwrap_or_revert();
297+
298+
if caller != state.admin {
299+
return Err(InvariantError::NotAdmin);
300+
}
301+
302+
state.protocol_fee = protocol_fee;
303+
304+
self.state.set(state);
305+
306+
Ok(())
307+
}
308+
309+
pub fn change_fee_receiver(
310+
&mut self,
311+
pool_key: PoolKey,
312+
fee_receiver: Address,
313+
) -> Result<(), InvariantError> {
314+
let caller = contract_env::caller();
315+
let state = self.state.get().unwrap_or_revert();
316+
let mut pool = self.pools.get(pool_key)?;
317+
318+
if caller != state.admin {
319+
return Err(InvariantError::NotAdmin);
320+
}
321+
322+
pool.fee_receiver = fee_receiver;
323+
self.pools.update(pool_key, &pool)?;
324+
325+
Ok(())
326+
}
327+
270328
pub fn is_tick_initialized(&self, key: PoolKey, index: i32) -> bool {
271329
self.tickmap.get(index, key.fee_tier.tick_spacing, key)
272330
}

0 commit comments

Comments
 (0)