1

I have written smartpy code to call an entrypoint swap on quipuswap dex v2 smart contract.

Here is the code for that

    @sp.entry_point
    def swap_tokens(self, amount_in, min_amount_out, direction):
        sp.set_type(amount_in, sp.TNat)
        sp.set_type(min_amount_out, sp.TNat)
        sp.set_type(direction, sp.TNat)
        set_direction = sp.local("set_direction", sp.variant("a_to_b", sp.unit))
        sp.if direction == sp.nat(1): 
            set_direction.value = sp.variant("b_to_a", sp.unit)
        sp.else:
            sp.if direction == sp.nat(0): 
                set_direction.value = sp.variant("a_to_b", sp.unit)
            sp.else:
                sp.failwith("INVALID_DIRECTION")
        get_swap_params_type = sp.contract(sp.TRecord(**{
                                                    "lambda" : sp.TOption(sp.TLambda(sp.TUnit, sp.TList(sp.TOperation))),
                                                    "swaps" : sp.TList(
                                                                sp.TRecord(
                                                                    direction = sp.TVariant(
                                                                        a_to_b = sp.TUnit,
                                                                        b_to_a = sp.TUnit
                                                                    ),
                                                                    pair_id = sp.TNat
                                                                ).layout(("direction", "pair_id"))
                                                            ),
                                                    "deadline" : sp.TTimestamp,
                                                    "receiver" : sp.TAddress,
                                                    "referrer" : sp.TAddress,
                                                    "amount_in" : sp.TNat,
                                                    "min_amount_out" : sp.TNat,
                                                    "referral_code" : sp.TOption(sp.TNat)
                                                }).layout(
                                                            ("lambda", 
                                                                ("swaps",
                                                                    ("deadline", 
                                                                        ("receiver", 
                                                                            ("referrer", 
                                                                                ("amount_in", 
                                                                                    ("min_amount_out", "referral_code")
                                                                                )
                                                                            )
                                                                        )
                                                                    )
                                                                )
                                                            )
                                                        ),
                                                self.data.dex_address,
                                                entry_point = "swap"
                                            ).open_some("Something is Wrong here")
                            
        get_swap_details_params_type = sp.TRecord(**{
                                                    "lambda" : sp.TOption(sp.TLambda(sp.TUnit, sp.TList(sp.TOperation))),
                                                    "swaps" : sp.TList(
                                                                sp.TRecord(
                                                                    direction = sp.TVariant(
                                                                        a_to_b = sp.TUnit,
                                                                        b_to_a = sp.TUnit
                                                                    ),
                                                                    pair_id = sp.TNat
                                                                ).layout(("direction", "pair_id"))
                                                            ),
                                                    "deadline" : sp.TTimestamp,
                                                    "receiver" : sp.TAddress,
                                                    "referrer" : sp.TAddress,
                                                    "amount_in" : sp.TNat,
                                                    "min_amount_out" : sp.TNat,
                                                    "referral_code" : sp.TOption(sp.TNat)
                                                }).layout(
                                                            ("lambda", 
                                                                 ("swaps",
                                                                      ("deadline", 
                                                                           ("receiver", 
                                                                                ("referrer", 
                                                                                     ("amount_in", 
                                                                                          ("min_amount_out", "referral_code")
                                                                                     )
                                                                                )
                                                                           )
                                                                      )
                                                                 )
                                                            )
                                                        )
        
        get_swap_details = sp.record(**{
                                "lambda" : sp.none,
                                "swaps" : [
                                             sp.record(
                                                direction = set_direction.value,
                                                pair_id = self.data.pool_id
                                            )
                                        ],
                                "deadline" : (sp.now).add_seconds(1800),
                                "receiver" : sp.sender,
                                "referrer" : sp.address("tz1Sw2mFAUzbkm7dkGCDrbeBsJTTtV7JD8Ey"),
                                "amount_in" : amount_in,
                                "min_amount_out" : min_amount_out,
                                "referral_code" : sp.none,
                            })

        transfer_params = sp.set_type_expr(get_swap_details, get_swap_details_params_type)
        sp.transfer(transfer_params, sp.amount, get_swap_params_type) 

Now, in this code the swap for b_to_a works fine. But a_to_b gives the following error

[
  {
    "kind": "temporary",
    "id": "proto.016-PtMumbai.michelson_v1.runtime_error",
    "contract_handle": "KT1F8Ei743RE8wH4BEdpq2uuqoHgb6jkfuJe"
  },
  {
    "kind": "temporary",
    "id": "proto.016-PtMumbai.michelson_v1.script_rejected",
    "location": 723,
    "with": {
      "int": "75"
    }
  }
]

Also, one thing to notice is if I use the same parameters and do a transaction directly on quipuswap dex v2 contract on better call dev. It works perfectly fine.

What might be the issue I am facing here?

1 Answer 1

5

The contract giving you this error is KT1F8Ei743RE8wH4BEdpq2uuqoHgb6jkfuJe, which is a FA1.2. The error code is 75.

Running Factori's analyze command,

factori analyze kt1 --network ghostnet KT1F8Ei743RE8wH4BEdpq2uuqoHgb6jkfuJe

we get (for this error code):

  Fail with 75 if ((GET (param.transfer.from, storage.balances) is None) /\ ((SENDER <> param.transfer.from)) /\ (not (storage.paused)) /\ ((SENDER <> storage.administrator)))
 Else
  Fail with 75 if ((GET (SENDER, [CAR;GET_OPT] (GET (param.transfer.from, storage.balances))) is None) /\ (GET (param.transfer.from, storage.balances) is Some) /\ ((SENDER <> param.transfer.from)) /\ (not (storage.paused)) /\ ((SENDER <> storage.administrator)))

where /\ can be read as the logical "and".

The error might be caused by the lack of allowance for the sender to perform the transfer on behalf of another address. In this case, the contract seems to check whether the sender has the required allowance to transfer tokens.

Here's what you can try to resolve the issue:

  • Make sure the sender has the required allowance to perform the transfer operation on behalf of the specified address in the amount_in parameter.

  • To set the allowance, you may need to call the approve entrypoint on the FA1.2 token contract. The spender should be set to the address of the contract you're interacting with (in this case, the QuipuSwap contract), and the value should be the amount you want to allow the contract to spend on behalf of the sender.

1
  • Adding to this ... The quipuswap v2 works in a manner that you need to send tokens to a contract that will call the dex as the swap function takes tokens from sender and not from source. What I changed I transferred tokens to be swapped to this contract that I wrote and then added a contract call to approve dex to transfer these tokens. Then it worked. Commented Apr 18, 2023 at 11:49

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.