Skip to content

Commit

Permalink
Merge pull request #6 from nervina-labs/develop
Browse files Browse the repository at this point in the history
Check NFT total value
  • Loading branch information
duanyytop authored Feb 26, 2024
2 parents 0fc7102 + 55ea095 commit e55f789
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 26 deletions.
24 changes: 15 additions & 9 deletions contracts/dex-lock/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use ckb_std::{

pub fn main() -> Result<(), Error> {
let args = DexArgs::from_script()?;
// When the inputs contain a cell whose lock script is owner, it means that the owner is
// cancelling the maker order.
// When the inputs contain a cell whose lock script is owner, it means that the owner can do
// anything including cancel the order
if inputs_contain_owner_cell(&args) {
return Ok(());
}
Expand All @@ -27,13 +27,19 @@ pub fn main() -> Result<(), Error> {
let dex_input_capacity = load_cell_capacity(dex_index, Source::Input)? as u128;
let output_capacity = load_cell_capacity(dex_index, Source::Output)? as u128;

// Prevent total_value(u128) from overflowing
let total_capacity = args
.total_value
.checked_add(dex_input_capacity)
.ok_or(Error::TotalValueOverflow)?;
if total_capacity > output_capacity {
return Err(Error::DexTotalValueNotMatch);
if args.is_nft() {
if args.total_value > output_capacity {
return Err(Error::DexNFTTotalValueNotMatch);
}
} else if args.is_udt() {
// Prevent total_value(u128) from overflowing
let total_capacity = args
.total_value
.checked_add(dex_input_capacity)
.ok_or(Error::TotalValueOverflow)?;
if total_capacity > output_capacity {
return Err(Error::DexFTTotalValueNotMatch);
}
}

Ok(())
Expand Down
5 changes: 3 additions & 2 deletions contracts/dex-lock/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ pub enum Error {
Encoding,
LockArgsInvalid = 5,
DexOwnerLockNotMatch,
DexTotalValueNotMatch,
DexFTTotalValueNotMatch,
DexNFTTotalValueNotMatch,
DexSetupInvalid,
TotalValueOverflow,
TotalValueOverflow = 10,
}

impl From<SysError> for Error {
Expand Down
13 changes: 11 additions & 2 deletions contracts/dex-lock/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const MIN_ARGS_SIZE: usize = 66;
pub struct DexArgs {
// the minimum length of serialized lock script is 49bytes
pub owner_lock: Script,
// 0b_xxxx_x0xx is for FT asset and 0b_xxxx_x1xx is for NFT asset
pub setup: u8,
pub total_value: u128,
}
Expand All @@ -33,8 +34,8 @@ impl DexArgs {

let owner_lock = Script::from_slice(&data[..owner_size]).map_err(|_e| Error::Encoding)?;
let setup = data[owner_size];
// If the third bit of setup is 0, it means FT(0b0000_0000), otherwise it means
// NFT(0b0000_0100)
// If the third bit of setup is 0, it means FT(0b_xxxx_x0xx), otherwise it means
// NFT(0b_xxxx_x1xx). The remaining bits are temporarily reserved or not implemented
if setup != 0 && setup != 4 {
return Err(Error::DexSetupInvalid);
}
Expand All @@ -47,6 +48,14 @@ impl DexArgs {
total_value,
})
}

pub fn is_udt(&self) -> bool {
self.setup | 0b0000_0000 == 0b0000_0000
}

pub fn is_nft(&self) -> bool {
self.setup & 0b0000_0100 == 0b0000_0100
}
}

pub fn position_dex_lock_in_inputs() -> Result<usize, Error> {
Expand Down
10 changes: 5 additions & 5 deletions tests/src/cancel_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ const MAX_CYCLES: u64 = 70_000_000;

// error numbers
const LOCK_ARGS_INVALID: i8 = 5;
const DEX_TOTAL_VALUE_NOT_MATCH: i8 = 7;
const DEX_FT_TOTAL_VALUE_NOT_MATCH: i8 = 7;

#[derive(PartialEq, Eq, Clone, Copy)]
enum DexError {
NoError,
LockArgsInvalid,
DexTotalValueNotMatch,
DexFTTotalValueNotMatch,
}

fn create_test_context(error: DexError) -> (Context, TransactionView) {
Expand Down Expand Up @@ -113,7 +113,7 @@ fn create_test_context(error: DexError) -> (Context, TransactionView) {
.previous_output(input_out_point2)
.build(),
];
if error != DexError::DexTotalValueNotMatch {
if error != DexError::DexFTTotalValueNotMatch {
inputs.push(
CellInput::new_builder()
.previous_output(input_out_point3)
Expand Down Expand Up @@ -181,8 +181,8 @@ fn test_dex_cancel_order_lock_args_error() {

#[test]
fn test_dex_cancel_order_owner_lock_not_match_error() {
let (context, tx) = create_test_context(DexError::DexTotalValueNotMatch);
let (context, tx) = create_test_context(DexError::DexFTTotalValueNotMatch);
// run
let err = context.verify_tx(&tx, MAX_CYCLES).unwrap_err();
assert_script_error(err, DEX_TOTAL_VALUE_NOT_MATCH);
assert_script_error(err, DEX_FT_TOTAL_VALUE_NOT_MATCH);
}
30 changes: 22 additions & 8 deletions tests/src/taker_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@ const MAX_CYCLES: u64 = 70_000_000;
// error numbers
const LOCK_ARGS_INVALID: i8 = 5;
const DEX_OWNER_LOCK_NOT_MATCH: i8 = 6;
const DEX_TOTAL_VALUE_NOT_MATCH: i8 = 7;
const DEX_SETUP_INVALID: i8 = 8;
const TOTAL_VALUE_OVERFLOW: i8 = 9;
const DEX_FT_TOTAL_VALUE_NOT_MATCH: i8 = 7;
const DEX_NFT_TOTAL_VALUE_NOT_MATCH: i8 = 8;
const DEX_SETUP_INVALID: i8 = 9;
const TOTAL_VALUE_OVERFLOW: i8 = 10;

#[derive(PartialEq, Eq, Clone, Copy)]
enum DexError {
NoError,
LockArgsInvalid,
DexOwnerLockNotMatch,
DexTotalValueNotMatch,
DexFTTotalValueNotMatch,
DexNFTTotalValueNotMatch,
DexSetupInvalid,
TotalValueOverflow,
}
Expand Down Expand Up @@ -68,6 +70,8 @@ fn create_test_context(error: DexError) -> (Context, TransactionView) {

let setup = if error == DexError::DexSetupInvalid {
3u8
} else if error == DexError::DexNFTTotalValueNotMatch {
4u8
} else {
0u8
};
Expand Down Expand Up @@ -135,8 +139,10 @@ fn create_test_context(error: DexError) -> (Context, TransactionView) {
.build(),
];

let output1_capacity = if error == DexError::DexTotalValueNotMatch {
let output1_capacity = if error == DexError::DexFTTotalValueNotMatch {
1234_5678_0000u64
} else if error == DexError::DexNFTTotalValueNotMatch {
1000_5678_0000u64
} else {
1234_5678_0000u64 + 300_0000_0000u64
};
Expand Down Expand Up @@ -208,11 +214,19 @@ fn test_dex_taker_order_owner_lock_not_match_error() {
}

#[test]
fn test_dex_taker_order_total_value_not_match_error() {
let (context, tx) = create_test_context(DexError::DexTotalValueNotMatch);
fn test_dex_ft_taker_order_total_value_not_match_error() {
let (context, tx) = create_test_context(DexError::DexFTTotalValueNotMatch);
// run
let err = context.verify_tx(&tx, MAX_CYCLES).unwrap_err();
assert_script_error(err, DEX_TOTAL_VALUE_NOT_MATCH);
assert_script_error(err, DEX_FT_TOTAL_VALUE_NOT_MATCH);
}

#[test]
fn test_dex_nft_taker_order_total_value_not_match_error() {
let (context, tx) = create_test_context(DexError::DexNFTTotalValueNotMatch);
// run
let err = context.verify_tx(&tx, MAX_CYCLES).unwrap_err();
assert_script_error(err, DEX_NFT_TOTAL_VALUE_NOT_MATCH);
}

#[test]
Expand Down

0 comments on commit e55f789

Please sign in to comment.