@skilesare @sea-snake
Hey guys. Been doing a lot of work with the PanIndustrial NFT libraries. They have been working really well so far! Amazing work!
Wanted to let you know I recently encountered a bug with the mops ICRC-37 Implementation:
https://mops.one/icrc37-mo
The error is in the transfer function:
public func transfer<system>(caller: Principal, transferFromArgs: [TransferFromArg]) : Result.Result<[?TransferFromResult], Text> {
//check that the batch isn't too big
let safe_batch_size = environment.icrc7.get_ledger_info().max_update_batch_size;
if(transferFromArgs.size() == 0){
return #err("no tokens provided");
//return [(transferFromArgstoken_ids[0], #Err(#GenericError({error_code = 12; message = "too many tokens transfered at one time"})))];
};
if(transferFromArgs.size() > safe_batch_size){
return #ok([?#Err(#GenericBatchError({message = "too many tokens transfered at one time"; error_code= 555}))]);
//return [(transferFromArgstoken_ids[0], #Err(#GenericError({error_code = 12; message = "too many tokens transfered at one time"})))];
};
let results = Vec.new<?TransferFromResult>();
label proc for(thisItem in transferFromArgs.vals()){
//check to and from account not equal
if(account_eq(thisItem.to, thisItem.from)){
Vec.add(results, ?#Err(#GenericError({message = "cannot transfer tokens to same account"; error_code=444})));
continue proc;
};
//test that the memo is not too large
let ?(memo) = testMemo(thisItem.memo) else {
Vec.add(results, ?#Err(#GenericError({message = "invalid memo. must be less than " # debug_show(environment.icrc7.get_ledger_info().max_memo_size) # " bits"; error_code=222})));
continue proc;
};
//make sure the approval is not too old or too far in the future
switch(testCreatedAt(thisItem.created_at_time, environment)){
case(#ok(val)) {};
case(#Err(#TooOld)){
Vec.add(results,?#Err(#TooOld));
continue proc;
};
case(#Err(#InTheFuture(val))) {
Vec.add(results, ?#Err(#CreatedInFuture({ledger_time = Nat64.fromNat(Int.abs(environment.get_time()))})));
continue proc;
};
};
debug if(debug_channel.transfer) D.print("calling token transfer" # debug_show(thisItem));
switch(transfer_token<system>(caller, thisItem)){
case(#ok(result)){
Vec.add(results, ?result);
};
case(#err(err)){
Vec.add(results, ?#Err(#GenericError({error_code = 394; message = err})));
};
};
return #ok(Vec.toArray(results));
};
return #ok(Vec.toArray(results));
};
The function allows for an array of TransferFromArgs, however, if you pass in an array of arguments, it prematurely returns due to the below line being in the loop for the TransferFromArgs:
return #ok(Vec.toArray(results));
Basically, the solution is just to get rid of the above line within the loop, because regardless the array of results will be returned at the end of the function once the loop is over.
Let me know if I interpreted it wrong, but when I commented out that line, it worked for passing in multiple arguments. Once again, this library is of huge help, thanks for all the great work. Thought I would bring this to your attention.