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()