liquidity icon indicating copy to clipboard operation
liquidity copied to clipboard

Add codes to a non used entry will cause `gas exhausted`

Open catsigma opened this issue 6 years ago • 0 comments

Contract with no problem

type token_storage = {
  balance_map : (address, nat) big_map;
  symbol : string;
  name : string;
  decimal : nat;
  total : nat;
}


type token_parameter = 
| Info of bytes contract
| Transfer of address * nat * (bytes contract * bytes) option
| Custom of nat * bytes

let%entry main (parameter : token_parameter) (storage : token_storage) =
  match parameter with
  | Info callback_contract ->
    ([Contract.call callback_contract 0tz (Bytes.pack (storage.symbol, storage.name, storage.decimal, storage.total))], storage)

  | Transfer (receiver_addr, amount, callback_option) ->
    let owner = Current.sender () in
    let owner_balance = 
      match Map.find owner storage.balance_map with
      | None -> 0p
      | Some x -> x
    in
    let (storage, owner_balance, receiver_balance) = match%nat owner_balance - amount with
      | Minus _ ->
        Current.failwith "balance insufficient"
      | Plus remain ->
        let balance_map = Map.update owner (Some remain) storage.balance_map in
        let receiver_balance = amount + (match Map.find receiver_addr storage.balance_map with | None -> 0p | Some x -> x) in
        let balance_map = Map.update receiver_addr (Some receiver_balance) balance_map in
        ((storage.balance_map <- balance_map), remain, receiver_balance)
    in
    let ops = 
      match callback_option with
      | None -> ([] : operation list)
      | Some (callback_contract, passing_bytes) ->
        [Contract.call callback_contract 0tz (Bytes.pack (passing_bytes, receiver_addr, amount, owner_balance, receiver_balance))]
    in
    (ops, storage)

  | Custom _ ->
    Current.failwith ()

Contract with problem

type reward_parameter = 
| Withdraw of nat * nat
| Deposit 
| Withdraw_unused
| Set of key_hash option * address option

type token_storage = {
  balance_map : (address, nat) big_map;
  symbol : string;
  name : string;
  decimal : nat;
  total : nat;
}


type token_parameter = 
| Info of bytes contract
| Transfer of address * nat * (bytes contract * bytes) option
| Custom of nat * bytes

let%entry main (parameter : token_parameter) (storage : token_storage) =
  match parameter with
  | Info callback_contract ->
    ([Contract.call callback_contract 0tz (Bytes.pack (storage.symbol, storage.name, storage.decimal, storage.total))], storage)

  | Transfer (receiver_addr, amount, callback_option) ->
    let owner = Current.sender () in
    let owner_balance = 
      match Map.find owner storage.balance_map with
      | None -> 0p
      | Some x -> x
    in
    let (storage, owner_balance, receiver_balance) = match%nat owner_balance - amount with
      | Minus _ ->
        Current.failwith "balance insufficient"
      | Plus remain ->
        let balance_map = Map.update owner (Some remain) storage.balance_map in
        let receiver_balance = amount + (match Map.find receiver_addr storage.balance_map with | None -> 0p | Some x -> x) in
        let balance_map = Map.update receiver_addr (Some receiver_balance) balance_map in
        ((storage.balance_map <- balance_map), remain, receiver_balance)
    in
    let ops = 
      match callback_option with
      | None -> ([] : operation list)
      | Some (callback_contract, passing_bytes) ->
        [Contract.call callback_contract 0tz (Bytes.pack (passing_bytes, receiver_addr, amount, owner_balance, receiver_balance))]
    in
    (ops, storage)

  | Custom _ ->
    let token = match Map.find (Current.sender ()) storage.balance_map with
      | None -> 0p
      | Some x -> x
    in
    let reward_contract = (KT1AAAAAAAAAAAAAAAAAAAAAAAAAAAreward : reward_parameter contract) in
    ([Contract.call reward_contract 0tz (Withdraw (token, storage.total))], storage)


If I call the two contracts with the same Transfer entry, they will cost gas in different(Although they have the same codes in Transfer entry). The first will cost less gas than the second one. I think it may be caused by the large cost of movement of stack values, don't know if it can be fixed.

catsigma avatar Aug 04 '18 07:08 catsigma