Skip to content

Add codes to a non used entry will cause gas exhausted #112

@catsigma

Description

@catsigma

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions