I am trying to replace get_contract with Tezos.get_entrypoint_opt I need to transfer FA1.2 tokens in Dex: https://github.com/madfish-solutions/quipuswap-core/blob/master/contracts/Dex.ligo#L21-L28

      operations := transaction(
         Transfer(Tezos.sender, this, tokenAmount), 
         case (Tezos.get_entrypoint_opt("%transfer", s.tokenAddress) : option(contract(x))) of Some(contr) -> contr
         | None -> (failwith("01"):contract(x))
         ) # operations;

But the entrypoint isn't found during execution. Deployed contract: https://better-call.dev/carthagenet/KT1PB7PCFS3F71FT8fbRmYsYX3ex8W7X5Vcw I have used this approach before and it worked fine:

operations := transaction(Transfer(Tezos.sender, this, tokenAmount), 0mutez, (get_contract(s.tokenAddress): contract(tokenAction))) # operations;

Deployed contract: https://better-call.dev/carthagenet/KT1KSpx5NY7FkY9PFBGRbYbui36rEF6agVWr Could someone advise something?

3 Answers 3


In LIGO entrypoint name corresponds to your router enum value types, not function names. So "Transfer" should start with uppercase letter.

In you case you should call it as follows: Tezos.get_entrypoint_opt("%Transfer", s.tokenAddress)


I think the entrypoint is well written ("%transfer") because if you look the generated Michelson code, the entrypoint annotations start with a low-case letter.

get_entrypoint_opt Ligo function is equivalent to CONTRACT %transfer {targeted_contract_entrypoints} in Michelson. And I reproduced this bug with a small michelson script like this one.

parameter address ;
storage bool;
code { CAR ;
       CONTRACT %increment (or (int %decrement) (int %increment)) ;
       IF_NONE { PUSH bool False } { DROP; PUSH bool True };
       NIL operation ;
       PAIR }

Notice that if you use get_contract_opt instead of get_entrypoint_opt then it generates an CONTRACT instruction without annotation.

CONTRACT  (or (int %decrement) (int %increment)) ;

and it works.


It depends on the "x"

let's say "x" is a variant (or (or (int %decrement) (unit %default)) (int %increment)) which represents entrypoints of the targeted contract.

  • get_contract({address}) returns a contract(x)
  • get_entrypoint_opt("%increment", {address}) returns a optional(contract(int))

Using get_entrypoint_opt function one must specify only the type of the parameter of the specified entrypoint (and not the parameter of the contract). Actually, it ensures that the contract at the given address possess an well-named entrypoint and with the expected type.

So I would say: replace the x by the right type. Find out what is expected by the entrypoint Transfer (i.e. Transfer of ...) ... I guess it must be (address * address * mutez) or in a record format .

I hope it helps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.