I am trying to build an arbitrage bot (learning) using AAVE flashloans, 0x and 1 Inch exchange swaps. While my flashloan call is successful but swap call to 0x exchange fails and revert 'SWAP_CALL_FAILED'. To examine I have tested both of my swap functions individually (by making them external payable and calling) and they work perfectly fine. But when I use them in my contract 0x swap fail.
Question - Could it be because the _zrxSwap (0x swap function) is an internal function? I can't seem to understand the reason.
My contract code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.6;
pragma experimental ABIEncoderV2;
import "./aave/FlashLoanReceiverBase.sol";
import "./aave/ILendingPoolAddressesProvider.sol";
import "./aave/ILendingPool.sol";
import "hardhat/console.sol";
import "./interfaces/IOneInchExchange.sol";
// A partial WETH interface.
interface IWETH is IERC20 {
function deposit() external payable;
function withdraw(uint256) external;
}
// Flashloan contract
contract Flashloan is FlashLoanReceiverBase {
uint public walletBalance = 0;
address payable beneficiary;
// The WETH contract.
IWETH public immutable WETH;
// One Inch Exchange Config
address ONE_INCH_EXCHANGE = 0x111111125434b319222CdBf8C261674aDB56F3ae;
// ZRX Config -- Mainet
address ZRX_EXCHANGE_PROXY_ADDRESS = 0xDef1C0ded9bec7F1a1670819833240f027b25EfF;
// Struct to pass calldata
struct MyCustomData {
address loanToken;
uint256 loanAmount;
uint256 repayAmount;
address arbToken;
bytes zrxData;
bytes oneData;
}
constructor(
address _addressProvider,
address payable _beneficiary,
IWETH weth
) FlashLoanReceiverBase(_addressProvider) public {
beneficiary = _beneficiary;
WETH = weth;
}
/**
This function is called after your contract has received the flash loaned amount
*/
function executeOperation(
address _reserve,
uint256 _amount,
uint256 _fee,
bytes calldata _params
)
external
override
{
MyCustomData memory mcd = abi.decode(_params, (MyCustomData));
require(_amount <= getBalanceInternal(address(this), _reserve), "Invalid balance, was the flashLoan successful?");
walletBalance = _amount;
// Arbitrage
_arb(mcd.loanToken, mcd.arbToken, mcd.loanAmount, mcd.zrxData, mcd.oneData);
uint totalDebt = _amount.add(_fee);
transferFundsBackToPoolInternal(_reserve, totalDebt);
}
function _arb(address _fromToken, address _toToken, uint256 _fromAmount, bytes memory _0xData, bytes memory _calldata) internal {
// Track original balance
uint256 _startBalance = IERC20(_fromToken).balanceOf(address(this));
// Perform the arb trade
_trade(_fromToken, _toToken, _fromAmount, _0xData, _calldata);
// Track result balance
uint256 _endBalance = IERC20(_fromToken).balanceOf(address(this));
// Require that arbitrage is profitable
require(_endBalance > _startBalance, "End balance must exceed start balance.");
}
function _trade(address _fromToken, address _toToken, uint256 _fromAmount, bytes memory _0xData, bytes memory _calldata) internal {
// Track the balance of the token RECEIVED from the trade
uint256 _beforeBalance = IERC20(_toToken).balanceOf(address(this));
// Swap on 0x: give _fromToken, receive _toToken
_zrxSwap(_fromToken, _fromAmount, _0xData);
// Calculate the how much of the token we received
uint256 _afterBalance = IERC20(_toToken).balanceOf(address(this));
// Read _toToken balance after swap
uint256 _toAmount = _afterBalance - _beforeBalance;
// Swap on 1Split: give _toToken, receive _fromToken
_oneSplitSwap(_toToken, _fromToken, _toAmount, _calldata);
}
// Swap back tokens on 0x exchange
function _zrxSwap(address _from, uint256 _amount, bytes memory _calldata) internal {
// Approve tokens
IERC20 _fromIERC20 = IERC20(_from);
// Approve zrx contract
require(_fromIERC20.approve(ZRX_EXCHANGE_PROXY_ADDRESS, uint256(-1)));
// Swap tokens
(bool success, ) = ZRX_EXCHANGE_PROXY_ADDRESS.call{value: _amount}(_calldata);
require(success, 'SWAP_CALL_FAILED');
// Reset approval
_fromIERC20.approve(ZRX_EXCHANGE_PROXY_ADDRESS, 0);
}
// Swap back tokens on 1 Inch exchange
function _oneSplitSwap(address _from, address _to, uint256 _amount, bytes memory _calldata) internal {
// Setup contracts
IERC20 _fromIERC20 = IERC20(_from);
IERC20 _toIERC20 = IERC20(_to);
IOneInchExchange _oneExchangeContract = IOneInchExchange(ONE_INCH_EXCHANGE);
// Approve tokens
_fromIERC20.approve(address(_oneExchangeContract), uint256(-1));
// Unpack the params
(IOneInchCaller caller, IOneInchExchange.SwapDescription memory desc, IOneInchCaller.CallDescription[] memory calls) = abi
.decode(_calldata, (IOneInchCaller, IOneInchExchange.SwapDescription, IOneInchCaller.CallDescription[]));
// Swap tokens: give _from, get _to
uint256 returnAmount = _oneExchangeContract.swap{ value: msg.value }(caller, desc, calls);
require(returnAmount > 0, '1INCH_SWAP_CALL_FAILED');
// Reset approval
_fromIERC20.approve(address(_oneExchangeContract), 0);
}
// Transfer ETH into this contract and wrap it into WETH.
function depositWETH()
external
payable
{
WETH.deposit{value: msg.value}();
}
/**
Flash loan 1000000000000000000 wei (1 ether) worth of `_asset`
*/
function flashloan(
address _loanToken,
uint256 _loanAmount,
address _arbToken,
bytes memory _zrxData,
bytes memory _calldata,
uint256 _gas
) public onlyOwner {
uint256 _repayAmount = _loanAmount.add(_gas);
bytes memory _params = abi.encode(MyCustomData({
loanToken: _loanToken,
loanAmount: _loanAmount,
repayAmount: _repayAmount,
arbToken: _arbToken,
zrxData: _zrxData,
oneData: _calldata
}));
uint amount = _loanAmount * 1e18;
ILendingPool lendingPool = ILendingPool(addressesProvider.getLendingPool());
lendingPool.flashLoan(address(this), _loanToken, amount, _params);
}
}
My Tx call:
const tx = {
from: owner,
to: flashloanAddress,
gas: 30000000,
data: flashloanContract.methods.flashloan(
fromAssetAddress,
1,
toAssetAddress,
zrx_data,
one_exchange_data,
total_gas
).encodeABI(),
}
Related
I new to solidity so could you guys please help me thanks? I tried to deploy the contract will ETH Value but always got the error "The transaction has been reverted to the initial state.
The called function should be payable if you send value and the value you send should be less than your current balance.".
Is there any way to fix this?
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
contract CustomToken is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol){
_mint(msg.sender, 1000000 * 10 ** 18);
}
}
contract Uniswap {
// Custom tokens to be initialiazed
string[] public tokens = ["CoinA", "CoinB", "CoinC"];
// map to maintain the tokens and its instances
mapping(string => ERC20) public tokenInstanceMap;
// 1 CoinA/CoinB/COinC = 0.0001 eth
uint256 ethValue = 100000000000000;
// 0.0001 eth = 1 CoinA/CoinB/CoinC
// 1 CoinA/CoinB/CoinC = 1 CoinA/CoinB/CoinC
constructor() {
for (uint i=0; i<tokens.length; i++) {
CustomToken token = new CustomToken(tokens[i], tokens[i]);
tokenInstanceMap[tokens[i]] = token;
}
}
function getBalance(string memory tokenName, address _address) public view returns (uint256) {
return tokenInstanceMap[tokenName].balanceOf(_address);
}
function getTotalSupply(string memory tokenName) public view returns (uint256) {
return tokenInstanceMap[tokenName].totalSupply();
}
function getName(string memory tokenName) public view returns (string memory) {
return tokenInstanceMap[tokenName].name();
}
function getTokenAddress(string memory tokenName) public view returns (address) {
return address(tokenInstanceMap[tokenName]);
}
function getEthBalance() public view returns (uint256) {
return address(this).balance;
}
function swapEthToToken(string memory tokenName) public payable returns (uint256) {
uint256 inputValue = msg.value;
uint256 outputValue = (inputValue / ethValue) * 10 ** 18; // Convert to 18 decimal places
require(tokenInstanceMap[tokenName].transfer(msg.sender, outputValue));
return outputValue;
}
}
I try with 0 ETH and it worked fine!
(https://i.stack.imgur.com/UtLNt.png)
However, with 1 ETH and it got error message
(https://i.stack.imgur.com/MsjE0.png)
A function needs to use the payable modifier in order to accept ETH.
When you're deploying a contract, it executes the constructor.
constructor(string memory name, string memory symbol) ERC20(name, symbol) payable {
_mint(msg.sender, 1000000 * 10 ** 18);
}
i got stucked in it and i don't understand where the error is...
Is a Lottery Project and the problem comes in placeABid function in lottery.sol contract.
Below i attached my code:
LotteryToken.sol
//SPDX-License-Identifier: MIT
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
pragma solidity ^0.8.4;
contract LotteryToken is Ownable, ERC20{
mapping(address=>uint)private _balances;
constructor(string memory name, string memory symbol, uint totalSupply)ERC20(name, symbol){
_mint(msg.sender, totalSupply);
_balances[msg.sender] = totalSupply;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) {
address owner = owner();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function _transfer(
address _from,
address _to,
uint _amount
)internal virtual override{
_balances[_from] -= _amount;
_balances[_to] += _amount;
super._transfer(_from, _to, _amount);
}
function balanceOf(address account)public view virtual override returns(uint){
return _balances[account];
}
}
Lottery.sol
//SPDX-License-Identifier: MIT
import "#openzeppelin/contracts/access/Ownable.sol";
import "./LotteryToken.sol";
import "./LotteryInfo.sol";
pragma solidity ^0.8.4;
contract Lottery is Ownable{
LotteryInfo private lotteryInfo;
LotteryToken private lotteryToken;
event BidCorrect(address bidder, uint tokenId, uint defaultBid);
constructor(){
}
function initLotteryTokenContract(address _lotteryTokenContract)public onlyOwner{
lotteryToken = LotteryToken(_lotteryTokenContract);
lotteryToken.increaseAllowance(address(this), lotteryToken.balanceOf(lotteryToken.owner()));
}
function initLotteryInfoContract(address _lotteryInfoContract)public onlyOwner{
lotteryInfo = LotteryInfo(_lotteryInfoContract);
}
function setItemToWin(
string memory _name,
uint _defaultBid,
uint _endingTimeLottery
)public onlyOwner{
require(_endingTimeLottery > block.timestamp, "Cannot set a date in the Past!");
lotteryInfo.setItemToWin(_name, _defaultBid, _endingTimeLottery);
}
function buyTokens(uint _quantity)external payable{
uint singleTokenPrice = 0.02 ether;
uint finalPrice = singleTokenPrice * _quantity;
require(msg.sender != owner() && msg.sender != lotteryToken.owner(), "Admin Cannot Buy Tokens!");
require(msg.value == finalPrice, "Please set the right price!");
payable(owner()).transfer(msg.value);
address lotterytokenOwner = lotteryToken.owner();
lotteryToken.transferFrom(lotterytokenOwner, msg.sender, _quantity);
}
function placeABid(uint _tokenIds)external{
require(block.timestamp < lotteryInfo.getEndingTimeLottery(_tokenIds), "Lottery is closed!");
require(msg.sender != owner() && msg.sender != lotteryToken.owner(), "Admin Cannot Place A Bid!");
uint requiredTokenAmounts = lotteryInfo.getDefaultItemBid(_tokenIds);
require(lotteryToken.balanceOf(msg.sender) >= requiredTokenAmounts, "No Necessary Funds To Partecipate!");
address lotteryTokenOwner = lotteryToken.owner();
lotteryToken.transferFrom(msg.sender, lotteryTokenOwner, requiredTokenAmounts);
lotteryInfo.updateBid(_tokenIds, requiredTokenAmounts);
lotteryInfo.updateAddress(_tokenIds, msg.sender);
emit BidCorrect(msg.sender, _tokenIds, requiredTokenAmounts);
}
There is another contract LotteryInfo but doesn't need to understand the problem.
What i want to do is to place a bid and send back the amount of bid to the lotteryToken.owner() but i receive error revert "ERC20 insufficient allowance".
Can someone explain me why?
Thanks a lot
You have to call "approve" method from the caller of "placeABid" function. He/She has to approve your Lottery contract to spend (calling transferFrom) he/shes ERC20 tokens. Without increasing the allowance (approval) of ERC20, you wont be able to withdraw ERC20 tokens from msg.sender.
You can detaily check ERC20 standart contract from OpenZeppelin library aswell.
First you have to call approve method from the caller of placeABid function. Then person has to approve your Lottery contract to spend (calling transferFrom) the ERC20 tokens. Without increasing the allowance (approval) of ERC20, you wont be able to withdraw ERC20 tokens from msg.sender.
If amount is the maximum uint256, the allowance is not updated on
* transferFrom. This is semantically equivalent to an infinite approval.
* Requirements:
- spender cannot be the zero address.
Here's a reference link
I have a contract deployed on goerli testnet but I don't understand why the contract balance doesn't increase after minting an nft.
Contract on goerli:
https://goerli.etherscan.io/address/0x41c13FF48Edc715612763394Ac8D36C4d11b5856
Succesful mint transaction:
https://goerli.etherscan.io/tx/0x4a0248639a427b2a824433dce5712d1d86bf85d8a7658d0215aff8cdc9448ea9
uint256 public constant TOTAL_SUPPLY = 100;
uint256 public constant MINT_PRICE = 0.02 ether;
uint256 public constant MAX_PUBLIC_MINT = 10;
function mintTo(address recipient, uint256 count) public payable {
uint256 tokenId = currentTokenId.current();
require(tokenId < TOTAL_SUPPLY, "Max supply reached");
require(
count > 0 && count <= MAX_PUBLIC_MINT,
"Max mint supply reached"
);
require(
msg.value == MINT_PRICE * count,
"Transaction value did not equal the mint price"
);
for (uint256 i = 0; i < count; i++) {
currentTokenId.increment();
uint256 newItemId = currentTokenId.current();
_safeMint(recipient, newItemId);
}
bool success = false;
(success, ) = owner().call{value: msg.value}("");
require(success, "Failed to send to owner");
}
I tried minting using hardhat:
task("mint", "Mints from the NFT contract")
.addParam("address", "The address to receive a token")
.setAction(async function (taskArguments, hre) {
const contract = await getContract("NftGame", hre);
const transactionResponse = await contract.mintTo(taskArguments.address, 1, {
gasLimit: 500_000,
value: ethers.utils.parseEther(String(0.02 * 1))
});
console.log(`Transaction Hash: ${transactionResponse.hash}`);
});
What balance should be incremented? Show us the entire contract.
If you mean the balance of the NFTs minted to some address, check the balanceOf(address) method.
But I think by "contract balance doesn't increase after minting an nft" you mean the ether balance of the contract does not increase after calling mintTo. The reason behind this can be found in line (success, ) = owner().call{value: msg.value}("");. The ether send with a tx when calling mintTo is sent to the owner of the contract. For this reason, the ether balance of the contract does not increase, but the ether balance of the contract owner should increase by msg.value. Look at the tx you provided, it says "TRANSFER 0.02 Ether From 0x41c13ff48edc715612763394ac8d36c4d11b5856 To 0x6c3455607f5592612e9e3754ba37c63123d68722" where 0x41c13ff48edc715612763394ac8d36c4d11b5856 is the address of the contract and 0x6c3455607f5592612e9e3754ba37c63123d68722 is the address of the owner of the contract.
How can I write to the blockchain after an undetermined, time-consuming execution result?
Situation:
Web Client (NextJS): User requests a long running process that can take up to 1 hour to complete. As a result of this transaction, a new contract instance should be written to the blockchain. We can't expect the client to stick around waiting => use a NodeJS or cloud function to delegate the long running task. Metamask on the client will define the contract owner.
Planning to use NextJS to route to a Moralis Cloud Fx to kick off the long running task. The result of this long running task will be digital content to store to the blockchain.
Constraints/Problem:
Can’t have the user wait for the process to complete
Metamask runs on the client
Need Moralis Cloud Fx or NodeJS to have access to the owner to instantiate the contract at an undetermined future point in time.
From: sequencediagram.org
title Long Running Task to Blockchain
actor User
User->UI:User Request
UI->NodeServer: Delegate Slow Tasks
activate NodeServer
NodeServer->RestService: Start slow process
activate RestService
RestService-->NodeServer: Confirmation ID
NodeServer-->UI: Confirmation ID
UI->Blockchain: Create empty contract
RestService->NodeServer: Result = Data for blockchain
deactivate RestService
NodeServer->Blockchain: **Public?** Contract.setRestResult(Result)
deactivate NodeServer
Here is how I was planning to approach setting up the contract that would straddle the client and server.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract EncryptionNFT is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private tokenCounter;
uint256 public fee_wei;
bool public isLocked; // has a user paid to access the resource?
string private confirmationId; // long temporary password
string private sensitiveData; // data produced by long running process
address public encryptionService; // service responsible for producing the sensitive data
address public licensor; // licensed process
uint256 public tokenID; // distinct contract id
bool private isMutexed = false; // Reentrancy guard
bool private isSensitiveDataSet = false; // Asserts can only be set 1 time
event unlockPaid(address receiver, uint256 amount);
event withdrawlMade(address receiver, uint256 amount);
constructor(string memory name, uint256 _fee_gwei, string memory _confirmationId, address _encryption_service, address _licensor)
ERC721(name, "DataX")
{
fee_wei = _fee_gwei * 1000000000; // assert numbers are in WEI
isLocked = true; // lock contract by default since data not available => owner shouldn't have to pay unless successful
confirmationId = _confirmationId; // assign temporary password
encryptionService = _encryption_service; // assign addresses for payments
licensor = _licensor; // assign addresses for payments
tokenID = tokenCounter.current(); // Set/Mint with distinct token id
_safeMint(msg.sender, tokenID);
tokenCounter.increment();
}
function unlock() public payable {
require(isLocked == true, "Contract already unlocked.");
require(msg.value >= fee_wei, "Not enough WEI to unlock NFT.");
require(isMutexed == false, "Reentrant call detected!");
isMutexed = true;
// DO PAYMENTS
uint256 rcv_payment = msg.value;
uint256 licensor_cut = rcv_payment / 10;
uint256 encryptor_cut = rcv_payment - licensor_cut;
(bool is_encryptor_success, ) = payable(encryptionService).call{value: encryptor_cut}("");
require(is_encryptor_success, "Encryptor transfer failed.");
emit unlockPaid(encryptionService, encryptor_cut);
(bool is_licensor_success, ) = payable(licensor).call{value: licensor_cut}("");
require(is_licensor_success, "Licensor transfer failed.");
emit unlockPaid(licensor, licensor_cut);
isLocked = false;
isMutexed = false;
}
function withdraw() public payable {
require(msg.sender == ownerOf(tokenID), "Only owner may withdraw.");
require(isLocked == false, "Contract must be unlocked.");
require(isMutexed == false, "Reentrant call detected!");
isMutexed = true;
// DO PAYMENTS
uint256 rcv_payment = msg.value;
uint256 nft_service_cut = rcv_payment / 10;
uint256 licensor_cut = nft_service_cut / 10;
uint256 encryptor_cut = rcv_payment - licensor_cut;
uint256 nft_owner_cut = rcv_payment - nft_service_cut;
(bool is_encryptor_success, ) = payable(encryptionService).call{value: encryptor_cut}("");
require(is_encryptor_success, "Encryptor transfer failed.");
emit withdrawlMade(encryptionService, encryptor_cut);
(bool is_licensor_success, ) = payable(licensor).call{value: licensor_cut}("");
require(is_licensor_success, "Licensor transfer failed.");
emit withdrawlMade(licensor, licensor_cut);
(bool is_nft_owner_success, ) = payable(ownerOf(tokenID)).call{value: nft_owner_cut}("");
require(is_nft_owner_success, "NFT Owner transfer failed.");
emit withdrawlMade(ownerOf(tokenID), nft_owner_cut);
isMutexed = false;
}
function setTokenURI(string memory _tokenURI) public {
require(_isApprovedOrOwner(_msgSender(), tokenID), "ERC721: transfer caller is not owner nor approved.");
_setTokenURI(tokenID, _tokenURI);
}
// Here's how I was planning to allow a server-side process to set the data on REST service completion (slow task)
function setSensitiveData(string memory _confirmationId, string memory _sensitiveData) public {
require(keccak256(bytes(_confirmationId)) == keccak256(bytes(confirmationId)), "Confirmation ID does not match.");
require(isSensitiveDataSet == false, "Sensitive Data has already been set");
sensitiveData = _sensitiveData;
isSensitiveDataSet = true;
}
function getSensitiveData() public view returns (string memory){
require(isSensitiveDataSet == true, "Sensitive Data must be set first.");
require(msg.sender == encryptionService, "Only encryption service accessible.");
return sensitiveData;
}
}
Edit I just found Moralis has a session that appears to allow server side access as a corresponding user. Has anyone played with this before? Would it work for this use case?
Moralis Docs
I want to create my own Eth token, using Ethereum wallet and the code from this simple tutorial given in the ethereum.org website.
I don't have a programming background, knowing only basic info about JS and need a lot of help.
Custom ETH tokens are used, for example, as ICO to fund tech-based teams. If I understand correctly, when a certain address receives ETH (sent by a person to an ICO), the "contract" made by this ICO sends him back a portion of the custom tokens.
Is this present in the code below?
How can I edit the "ratio" between ETH and the custom token (example: you send 1 ETH and receive 588 c.tokens - ratio 1:588)?
pragma solidity ^0.4.8;
contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract MyToken {
/* Public variables of the token */
string public standard = 'Token 0.1';
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
/* This generates a public event on the blockchain that will notify clients */
event Transfer(address indexed from, address indexed to, uint256 value);
/* This notifies clients about the amount burnt */
event Burn(address indexed from, uint256 value);
/* Initializes contract with initial supply tokens to the creator of the contract */
function MyToken(
uint256 initialSupply,
string tokenName,
uint8 decimalUnits,
string tokenSymbol
) {
balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
totalSupply = initialSupply; // Update total supply
name = tokenName; // Set the name for display purposes
symbol = tokenSymbol; // Set the symbol for display purposes
decimals = decimalUnits; // Amount of decimals for display purposes
}
/* Send coins */
function transfer(address _to, uint256 _value) {
if (_to == 0x0) throw; // Prevent transfer to 0x0 address. Use burn() instead
if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
balanceOf[msg.sender] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
Transfer(msg.sender, _to, _value); // Notify anyone listening that this transfer took place
}
/* Allow another contract to spend some tokens in your behalf */
function approve(address _spender, uint256 _value)
returns (bool success) {
allowance[msg.sender][_spender] = _value;
return true;
}
/* Approve and then communicate the approved contract in a single tx */
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
}
/* A contract attempts to get the coins */
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
if (_to == 0x0) throw; // Prevent transfer to 0x0 address. Use burn() instead
if (balanceOf[_from] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
if (_value > allowance[_from][msg.sender]) throw; // Check allowance
balanceOf[_from] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
allowance[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
return true;
}
function burn(uint256 _value) returns (bool success) {
if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough
balanceOf[msg.sender] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
Burn(msg.sender, _value);
return true;
}
function burnFrom(address _from, uint256 _value) returns (bool success) {
if (balanceOf[_from] < _value) throw; // Check if the sender has enough
if (_value > allowance[_from][msg.sender]) throw; // Check allowance
balanceOf[_from] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
Burn(_from, _value);
return true;
}
}
1) get amount of custom token (msg.value/ratioAmount)
2) transfer that amount to the requester
you have to use a payable fallback function in which you should call a function which will be dealing with above two mentioned activities.
Send() will invoke payable fallback function which in turn call your custom function which will be doing the actual work.
Check fallback function in solidity documentation.
payable is necessary for send() after DAO incident.