Skip to content

Commit b4f14ce

Browse files
committed
adding commission token management processors without double-spending check
1 parent 904a0dc commit b4f14ce

File tree

2 files changed

+130
-5
lines changed

2 files changed

+130
-5
lines changed

commission/program/src/merkle.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,32 @@ use crate::state::CommissionToken;
99

1010
const SOLANA_NATIVE_DECIMALS: u8 = 9u8;
1111

12+
#[derive(Clone)]
13+
pub enum OperationType {
14+
AddToken,
15+
RemoveToken,
16+
UpdateToken,
17+
}
18+
19+
impl std::convert::Into<u8> for OperationType {
20+
fn into(self) -> u8 {
21+
match self {
22+
OperationType::AddToken => 1,
23+
OperationType::RemoveToken => 2,
24+
OperationType::UpdateToken => 3,
25+
}
26+
}
27+
}
1228

1329
pub struct CommissionTokenData {
30+
pub operation_type: OperationType,
1431
pub token: CommissionToken,
1532
}
1633

1734
impl CommissionTokenData {
18-
pub fn new_data(token: CommissionToken) -> Self {
35+
pub fn new_data(operation_type: OperationType, token: CommissionToken) -> Self {
1936
CommissionTokenData {
37+
operation_type,
2038
token,
2139
}
2240
}
@@ -26,6 +44,8 @@ impl Data for CommissionTokenData {
2644
fn get_operation(&self) -> Vec<u8> {
2745
let mut data = Vec::new();
2846

47+
data.push(self.operation_type.clone().into());
48+
2949
match self.token.token {
3050
lib::CommissionToken::Native => {
3151
// Nothing to add

commission/program/src/processor.rs

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use spl_associated_token_account::get_associated_token_address;
1313
use spl_associated_token_account::instruction::create_associated_token_account;
1414
use solana_program::secp256k1_recover::SECP256K1_PUBLIC_KEY_LENGTH;
1515
use lib::merkle::{ContentNode, get_merkle_root};
16-
use crate::merkle::CommissionTokenData;
16+
use crate::merkle::{CommissionTokenData, OperationType};
1717
use lib::ecdsa::verify_ecdsa_signature;
1818
use lib::instructions::commission::{CommissionInstruction, CommissionTokenArg, MAX_ADMIN_SIZE};
1919
use lib::error::LibError;
@@ -40,11 +40,11 @@ pub fn process_instruction<'a>(
4040
}
4141
CommissionInstruction::RemoveFeeToken(args) => {
4242
msg!("Instruction: Remove fee token");
43-
Ok(())
43+
process_remove_token(program_id, accounts, args.origin, args.signature, args.recovery_id, args.path, args.token)
4444
}
4545
CommissionInstruction::UpdateFeeToken(args) => {
4646
msg!("Instruction: Update fee token");
47-
Ok(())
47+
process_update_token(program_id, accounts, args.origin, args.signature, args.recovery_id, args.path, args.token)
4848
}
4949
}
5050
}
@@ -198,13 +198,118 @@ pub fn process_add_token<'a>(
198198
commission_admin_info.key.to_bytes(),
199199
program_id.to_bytes(),
200200
Box::new(
201-
CommissionTokenData::new_data(CommissionToken::from(&token))
201+
CommissionTokenData::new_data(OperationType::AddToken, CommissionToken::from(&token))
202202
),
203203
);
204204
let root = get_merkle_root(content, &path)?;
205205
verify_ecdsa_signature(root.as_slice(), signature.as_slice(), recovery_id, bridge_admin.public_key)?;
206206

207+
commission_admin.acceptable_tokens.push(CommissionToken::from(&token));
208+
commission_admin.serialize(&mut *commission_admin_info.data.borrow_mut())?;
209+
Ok(())
210+
}
211+
212+
pub fn process_remove_token<'a>(
213+
program_id: &'a Pubkey,
214+
accounts: &'a [AccountInfo<'a>],
215+
origin: [u8; 32],
216+
signature: [u8; SECP256K1_PUBLIC_KEY_LENGTH],
217+
recovery_id: u8,
218+
path: Vec<[u8; 32]>,
219+
token: CommissionTokenArg,
220+
) -> ProgramResult {
221+
let account_info_iter = &mut accounts.iter();
222+
223+
let commission_admin_info = next_account_info(account_info_iter)?;
224+
let bridge_admin_info = next_account_info(account_info_iter)?;
225+
226+
let commission_key = Pubkey::create_program_address(&[lib::COMMISSION_ADMIN_PDA_SEED.as_bytes(), bridge_admin_info.key.as_ref()], &program_id)?;
227+
if commission_key != *commission_admin_info.key {
228+
return Err(LibError::WrongAdmin.into());
229+
}
230+
231+
let mut commission_admin: CommissionAdmin = BorshDeserialize::deserialize(&mut commission_admin_info.data.borrow_mut().as_ref())?;
232+
if commission_admin.is_initialized {
233+
return Err(LibError::NotInitialized.into());
234+
}
235+
236+
let bridge_admin: BridgeAdmin = BorshDeserialize::deserialize(&mut bridge_admin_info.data.borrow_mut().as_ref())?;
237+
if !bridge_admin.is_initialized {
238+
return Err(LibError::NotInitialized.into());
239+
}
240+
241+
let content = ContentNode::new(
242+
origin,
243+
commission_admin_info.key.to_bytes(),
244+
program_id.to_bytes(),
245+
Box::new(
246+
CommissionTokenData::new_data(OperationType::RemoveToken, CommissionToken::from(&token))
247+
),
248+
);
249+
let root = get_merkle_root(content, &path)?;
250+
verify_ecdsa_signature(root.as_slice(), signature.as_slice(), recovery_id, bridge_admin.public_key)?;
251+
252+
let token_to_remove = CommissionToken::from(&token);
253+
for i in 0..commission_admin.acceptable_tokens.len() {
254+
if commission_admin.acceptable_tokens[i].eq(&token_to_remove) {
255+
commission_admin.acceptable_tokens.remove(i);
256+
break;
257+
}
258+
}
259+
260+
commission_admin.serialize(&mut *commission_admin_info.data.borrow_mut())?;
261+
Ok(())
262+
}
207263

264+
pub fn process_update_token<'a>(
265+
program_id: &'a Pubkey,
266+
accounts: &'a [AccountInfo<'a>],
267+
origin: [u8; 32],
268+
signature: [u8; SECP256K1_PUBLIC_KEY_LENGTH],
269+
recovery_id: u8,
270+
path: Vec<[u8; 32]>,
271+
token: CommissionTokenArg,
272+
) -> ProgramResult {
273+
let account_info_iter = &mut accounts.iter();
274+
275+
let commission_admin_info = next_account_info(account_info_iter)?;
276+
let bridge_admin_info = next_account_info(account_info_iter)?;
277+
278+
let commission_key = Pubkey::create_program_address(&[lib::COMMISSION_ADMIN_PDA_SEED.as_bytes(), bridge_admin_info.key.as_ref()], &program_id)?;
279+
if commission_key != *commission_admin_info.key {
280+
return Err(LibError::WrongAdmin.into());
281+
}
282+
283+
let mut commission_admin: CommissionAdmin = BorshDeserialize::deserialize(&mut commission_admin_info.data.borrow_mut().as_ref())?;
284+
if commission_admin.is_initialized {
285+
return Err(LibError::NotInitialized.into());
286+
}
287+
288+
let bridge_admin: BridgeAdmin = BorshDeserialize::deserialize(&mut bridge_admin_info.data.borrow_mut().as_ref())?;
289+
if !bridge_admin.is_initialized {
290+
return Err(LibError::NotInitialized.into());
291+
}
292+
293+
let content = ContentNode::new(
294+
origin,
295+
commission_admin_info.key.to_bytes(),
296+
program_id.to_bytes(),
297+
Box::new(
298+
CommissionTokenData::new_data(OperationType::UpdateToken, CommissionToken::from(&token))
299+
),
300+
);
301+
let root = get_merkle_root(content, &path)?;
302+
verify_ecdsa_signature(root.as_slice(), signature.as_slice(), recovery_id, bridge_admin.public_key)?;
303+
304+
let token_to_update = CommissionToken::from(&token);
305+
for i in 0..commission_admin.acceptable_tokens.len() {
306+
if commission_admin.acceptable_tokens[i].token.eq(&token_to_update.token) {
307+
commission_admin.acceptable_tokens[i].amount = token_to_update.amount;
308+
break;
309+
}
310+
}
311+
312+
commission_admin.serialize(&mut *commission_admin_info.data.borrow_mut())?;
208313
Ok(())
209314
}
210315

0 commit comments

Comments
 (0)