Here's a more complete example, with the caveat that:
DONT USE THIS AS IS, IT ALLOWS ANYONE TO TRANSFER MONEY OUT.
The trick here is that before you deposit tokens, you have to approve the contract first.
Example.sol:
// SPDX-License-Identifier: MIT
pragma solidity >0.8.5;
import "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract SomeCoin is ERC20 {
constructor() ERC20("SC", "Some Coin") {
_mint(msg.sender, 1000000000);
}
}
contract Example {
// DONT USE THIS AS IS
// IT ALLOWS ANYONE TO TRANSFER TOKENS OUT
// INSTEAD, KEEP TRACK OF THE USER BALANCES SEPERATELY
IERC20 public erc20coin;
constructor(address erc20Address_){
erc20coin = IERC20(erc20Address_);
}
function deposit(uint amount_)external{
erc20coin.transferFrom(msg.sender, address(this), amount_);
}
function withdrawInto(address to_, uint amount_, address contractAddress_)external{
IERC20 erc20 = IERC20(contractAddress_);
erc20.transfer(to_, amount_);
}
function withdrawInto(address to_, uint amount_)external{
erc20coin.transfer(to_, amount_);
}
}
And for a quick example of how to run it (in Python, sorry JS users, but
you can see what I'm doing here and replicate it i'm sure):
example.py:
#!/usr/bin/env python3
from kista import *
w3 = w3_connect(0)
def status():
print("-"30)
print("Example balance", c.balanceOf( e.address))
print("address 0 balance", c.balanceOf(a[0].address))
print("address 1 balance", c.balanceOf(a[1].address))
print("address 2 balance", c.balanceOf(a[2].address))
print("-"30)
pass
if name == 'main':
a = [WrapAccount(a) for a in range(10)]
c = WrapContract(force_load_contract_address(
"SomeCoin", reload = True))
e = WrapContract(force_load_contract_address(
"Example", c.address, reload = True))
status()
print(c.approve(e.address, 150000000))
print(e.deposit(100000000))
status()
print(e.withdrawInto(a[1].address, 2500))
print(e.withdrawInto(a[2].address, 2500, c.address))
status()
Basically, I can call IERC20(_tokenContract1) from inside any contract I own to invoke IERC20(_tokenContract) from a contract I do not own? I have to have the IERC spec implemented in my own contract of course correct on all of this???
I really appreciate it Ill test and give you the win! :)
– lopezdp Jul 19 '21 at 15:42this is executed from the dApp itself using ethers or web3 correct? Can you provide an example of how I can call approve using ethers for example please?
if you dm me and send me a wallet address ill send you some ETH too if the answer gives me the result I want. ill set this up now to give you time to answer my follow up questions/comments also and I will send payment on successful test. Dont forget to DM me with wallet please.
– lopezdp Jul 19 '21 at 15:43
– Keerthana Ramalingam Jul 20 '21 at 08:50let contract = new ethers.Contract(contractAddress, contracObj.contractAbi, this.provider); let contractWithSigner = contract.connect(wallet); let rawTx = { gasLimit: 500000 }; await contractWithSigner.approve(toAccount, accountNum, rawTx);