Error with Deposit of Pangolin Liquidity Tokens: " ds-math-sub-underflow"

Developing a new decentralized application to interact with Pangolin rewards. Users have to deposit their Pangolin tokens into the contract. Following the approval, I am getting the following error when trying to deposit:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error. { “code”: 3, “message”: “execution reverted: ds-math-sub-underflow”, “data”: “0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001564732d6d6174682d7375622d756e646572666c6f770000000000000000000000” }

I am minting a new token to provide as a receipt of the deposit. Would love some support and insight. Using Web3 injection on Metamask to connect with the Fuji network.

 function deposit(uint256 _amount) public {
    uint256 _pool = balance();
    uint256 _before = token.balanceOf(address(this));
    token.safeTransferFrom(msg.sender, address(this), _amount);
    uint256 _after = token.balanceOf(address(this));
    _amount = _after.sub(_before); // Additional check for deflationary tokens
    uint256 shares = 0;
    if (totalSupply() == 0) {
        shares = _amount;
    } else {
        shares = (_amount.mul(totalSupply())).div(_pool);
    _mint(msg.sender, shares);


The best place to receive direct help for this kind of question would be on
in developers-chat.


1 Like

Posted there as well. The conversation moves fast there sometimes and it is sharded environment that prevents some problems/answers being readily available to the world.

Update on my progress:
I tried commenting out _after.sub(_before) because I thought it may be an issue with the safe math from the substraction. However, the issue persisted. I am assuming it is the SafeTransfer function now. Within that function is this callOptionRetun which is using a low level call. Could this be causing my issue?

     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");

Further investigation is leading me to think it may be the interface with the Pangolin Router. It is the only place I can find this particular error aside from the uniswap router.

If anyone has insight, i would appreciate it. I think i am missing an approval or allowance


The issue is that the token being referenced was a Pangolin pair. Therefore, I was receiving the ds-math-sub-underflow because I needed to approve the smart contract I was using to be able to use the transferFrom from the Pangolin pair. Once I understood this, it was relatively easy to resolve. Understanding that the approval needed to be done through the other contract was the missing component.