I have the following AlgoToken contract:

interface StableCoin {
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

contract AlgoToken is ERC20{

    using ABDKMathQuad for uint256;
    using ABDKMathQuad for int256;
    using ABDKMathQuad for bytes16;

    StableCoin public stable_coin;

    function buy(uint $USD_amount) public payable {
        //do a bunch of stuff to calculate algos_to_mint

        stable_coin.transferFrom(msg.sender, address(this), $USD_amount);
        _mint(msg.sender, algos_to_mint);

    function sell(uint $algo_amount) public payable{
       // do a bunch of stuff to calculate $USD_to_send

       _burn(msg.sender, $algo_amount);
       stable_coin.transferFrom(address(this), msg.sender, $USD_to_send);

In python I have the following brownie deployments:

USDS_Token = ERC20_public_mint.deploy("Stable Coin", "USDS", {'from': accounts[0]})
algoToken = AlgoToken.deploy(
    "Price growth Algo Token",\
    "Algo", \
    {"from": accounts[1]}\

ERC20_public_mint is an ERC20 with a public mint function:

    function mint(address account, uint256 amount) public {
        _mint(account, amount);

I also have a python buy function:

def buy(USD_amount):
    USDS_Token.mint(USDS_Token.address, USD_amount)
    USDS_Token.approve(algoToken.address, USD_amount)
    USDS_Token.increaseAllowance(algoToken.address, USD_amount)
    contract_function = algoToken.buy(USD_amount)
    tx_hash = contract_function.transact({"from": accounts[0], "account": USDC_Token.address, "amount": math.floor(USD_amount)})
    return tx_hash

No matter what I do I get an error on algoToken.buy(USD_amount). The current code yields the following error:

Transaction sent: 0x51706233d36caf15a92ba04c599a38c3203b4feed005abbc01c6d6adc6d81b7d
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 1
  AlgoToken.buy confirmed (ERC20: insufficient allowance)   Block: 6   Gas used: 280614 (2.34%)

Traceback (most recent call last):
  File "tests/test-price-growth-algo-token.py", line 197, in <module>
  File "tests/test-price-growth-algo-token.py", line 138, in buy
    contract_function = algoToken.buy(USD_amount)
  File "/home/steve/.local/lib/python3.8/site-packages/brownie/network/contract.py", line 1864, in __call__
    return self.transact(*args)
  File "/home/steve/.local/lib/python3.8/site-packages/brownie/network/contract.py", line 1737, in transact
    return tx["from"].transfer(
  File "/home/steve/.local/lib/python3.8/site-packages/brownie/network/account.py", line 682, in transfer
  File "/home/steve/.local/lib/python3.8/site-packages/brownie/network/transaction.py", line 446, in _raise_if_reverted
    raise exc._with_attr(
brownie.exceptions.VirtualMachineError: revert: ERC20: insufficient allowance
Trace step -1, program counter 4635:
  File "contracts/price-growth-algo-token.sol", line 274, in AlgoToken.buy:
        idealized_Mcap = K_target.mul(f_slip).add(f_peg);
        target_Mcap = price.mul(f_hyp_supply);

        stable_coin.transferFrom(msg.sender, address(this), $USD_amount);
        _mint(msg.sender, algos_to_mint);


I experimented with a zillion ways to structure the buy functions but everything I've tried has resulted in errors. How can I use brownie to send ERC20 tokens to the algoToken contract by calling the algoToken.buy function?


Your Answer

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