Me: A
ERC20 tokens:Coin
ERC20 tokens:Fund
Deployer for both tokens is the same account: Z
counterpart:B
I want to move the same amount of Coin from Z to B when A burns the Fund
"If you send ""thank you"" from A to B, you will receive a coin from Z to B."
The development is done with Remix's VM
Solidty for Coin
//SPDX-License-Identifier: GPL-2.0
pragma solidity^0.6.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/SafeERC20.sol";
contract Coin is ERC20 {
address private_MakerAddress;
US>//#string private_Message=";
US>string public version;
constructor(
US>string memory name,
string memory symbol,
uint256 initial_supply,
US>string memory version_
) public ERC20(name, symbol){
_MakerAddress=msg.sender;
_mint(msg.sender, initial_supply);
version=version_;
}
function addCoin(uint256amount)public returns(uint256){
_mint(msg.sender, amount);
}
function transferWithMessage(address recipient, uint256amount, string memory message) public payable returns(bool) {
_Message=message;
_transfer(_msgSender(), recipient, amount);
return true;
}
function getMakerAddress()public view returns(address){
return_MakerAddress;
}
}
Fund Solidty
//SPDX-License-Identifier: GPL-2.0
pragma solidity^0.6.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/SafeERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
contract FundManager is ERC20 {
address private_MakerAddress;
US>//#string private_Message=";
US>//#string private_version=";
address payable private_coinTokenOwner;
IERC20 private_coinToken;
event Realize(uint256amount, address receiver, string message);
constructor(
US>string memory name,
string memory symbol,
uint256 initial_supply,
string memory version,
address payable coinTokenOwner,
IERC20 coinToken
) public ERC20(name, symbol){
_MakerAddress=msg.sender;
_mint(msg.sender, initial_supply);
_version=version;
_coinTokenOwner=coinTokenOwner;
_coinToken=coinToken;
}
function addFund(uint256amount) public returns(uint256){
_mint(msg.sender, amount);
}
function getVersion()public view returns(string memory){
return_version;
}
function getMakerAddress()public view returns(address){
return_MakerAddress;
}
function realize(uint256_amount, address_receiver, string memory_message)public{
permit Realize(_amount,_receiver,_message);
super._burn(msg.sender,_amount);
_coinToken.approve(_coinTokenOwner,_amount);
_coinToken.transferFrom(_coinTokenOwner,_receiver,_amount);
}
}
realize
is a function that I want to burn the fund and send money
It works from Z to A, but when A executes realize
, the following error occurs
transact to FundManager.realize error:VM error: revert.revert The transaction has been reversed to the initial state. Reason provided by the contract: "ERC20:transfer amount exceeds allowance".Debug the transaction to get more information.
transferFrom
can be used for third-party remittance, but is it wrong to use it?
I'm starting to think that it's technically impossible to move someone else's token on my own request while making it myself.
I would appreciate it if you could give me an idea in that case.
Additional information
As the description method was pointed out, this is a summary.
I reconsidered FundManager
(I have removed part of Burn so that I can run it many times in the test.)
//SPDX-License-Identifier: GPL-2.0
pragma solidity^0.6.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/SafeERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
contract FundManager is ERC20 {
address private_MakerAddress;
US>//#string private_Message=";
US>//#string private_version=";
address private_coinTokenOwner;
IERC20 private_coinToken;
event Realize(uint256amount, address receiver, string message);
constructor(
US>string memory name,
string memory symbol,
uint256 initial_supply,
string memory version,
address coinTokenOwner,
IERC20 coinToken
) public ERC20(name, symbol){
_MakerAddress=msg.sender;
_mint(msg.sender, initial_supply);
_version=version;
_coinTokenOwner=coinTokenOwner;
_coinToken=coinToken;
}
function realizeAllowance(uint256_amount, address_receiver, string memory_message)public returns(bool){
require(_amount>0);
require(_receiver!=address(0);
permit Realize(_amount,_receiver,_message);
_coinToken.allowance(_coinTokenOwner,_receiver);
return true;
}
function realizeApproval(address_receiver, uint256_amount)public returns(bool){
require(_amount>0);
require(msg.sender!=address(0);
_coinToken.approve(_receiver,_amount);
return true;
}
function realizeTransferFrom(address_receiver, uint256_amount)public returns(bool){
require(_amount>0);
require(msg.sender!=address(0);
require(_receiver!=address(0);
_coinToken.transferFrom(_coinTokenOwner,_receiver,_amount);
return true;
}
}
realizeAllowance
Run as yourself(A)
realizeApproval
Run as Owner(Z)
realizeTransferFrom
Run as yourself(A)
realizeApproval
I thought I was running it as Owner(Z), but it was running from Fund, so it was the address of Fund.
owner:Fund address
spender:B
I got a value when I ran it in
Is it wrong to approve from Fund?
I hope it will be helpful
ethereum solidity
I reviewed various things and worked with the following contents.
I haven't put in the Burn part yet, but
//SPDX-License-Identifier: GPL-2.0
pragma solidity^0.6.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/SafeERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
contract FundManager is ERC20 {
address private_MakerAddress;
US>//#string private_Message=";
US>//#string private_version=";
address private_coinTokenOwner;
IERC20 private_coinToken;
event Realize(uint256amount, address receiver, string message);
constructor(
US>string memory name,
string memory symbol,
uint256 initial_supply,
string memory version,
address coinTokenOwner,
IERC20 coinToken
) public ERC20(name, symbol){
_MakerAddress=msg.sender;
_mint(msg.sender, initial_supply);
_version=version;
_coinTokenOwner=coinTokenOwner;
_coinToken=coinToken;
}
function addFund(uint256amount) public returns(uint256){
_mint(msg.sender, amount);
}
function getVersion()public view returns(string memory){
return_version;
}
function getMakerAddress()public view returns(address){
return_MakerAddress;
}
function realize(uint256_amount, address_receiver, string memory_message)public returns(bool){
require(msg.sender!=address(0);
require(_amount>0);
require(_receiver!=address(0);
permit Realize(_amount,_receiver,_message);
_coinToken.allowance(address(this),_receiver);
_coinToken.approve(_receiver,_amount);
_coinToken.transfer(_receiver,_amount);
return true;
}
function getCoinBalance() public view returns(uint256) {
return_coinToken.balanceOf(address(this)));
}
}
The problem seems to have started with not knowing that when accessing a smart contract from a smart contract, the address becomes the address of the smart contract, not the address at runtime.
I would appreciate it if you could point out any security issues.
Thank you very much
© 2024 OneMinuteCode. All rights reserved.