# Impossible to transfer my token via Token.transfer or Token.transferFrom

Everytime I’m trying to make a transfer I’m having an error, every other methods seems to work except transfer & transferFrom.

I’m having an issue with my “token.transfer” (token is my ERC20), even with token.transferFrom this is the message displayed on truffle :

Error: Transaction: 0x986f88e4e918e3b69448abce5bd88ca7d80c4f078496e5ff624d3dc69d476977 exited with an error (status 0). Please check that the transaction: - satisfies all conditions set by Solidity require statements. - does not trigger a Solidity revert statement.

Other methods are working well like token.balanceOf, token.approve, etc.

And via metamask It seems to work also, on the TX it is the transfer method (_to, _amount) which is used.

Deployment:

const BTUToken = artifacts.require(‘./BTU.sol’);
const BTUTokenSale = artifacts.require(‘./BTUTokenSale.sol’);
const RES = artifacts.require(‘./RES.sol’);

module.exports = function(deployer, network, accounts) {
console.log(accounts[0]);
};


—————————————

SmartContract for the BTU Token: 0x4177ce724ae517d58db1eada280633853bdfebe1) I did it with OpenZeppelin

contract RES {

}

……………………

function requestReservation(string _bookingId, uint256 _depositAmount, address _providerId, uint32 _freeCancelDateTs) public payable {
require(token.balanceOf(msg.sender) >= _depositAmount);
bookings[_bookingId] = Booking(_bookingId, _depositAmount, _providerId, _freeCancelDateTs);
token.transfer(this, _depositAmount);
}


I hope you can help me, I’m stuck since 2weeks on this problem.

Thank you !

I think the problem is happening on this line in your requestReservation function:

token.transfer(this, _depositAmount);


This line causes the RES smart contract to try to transfer its own tokens to itself, because the smart contract is calling transfer, not the user. I suspect that you want to transfer the user's tokens. This is not possible with the transfer(..) function. If any smart contract could take anyone's tokens, that would be a huge security leak.

The most common way to solve this problem is to have the user approve tokens to the RES smart contract. Then, the RES smart contract can use something like token.transferFrom(msg.sender, this, _depositAmount);

This requires the user to perform two transactions: One to call approve on the token contract, and one to call requestReservation on the RES smart contract. To make it work with only 1 transaction, people often add an approveAndCall function to the token contract. I'm sure you will be able to find example code for that.

• Thank you Jesse, I will try again with transferFrom, the problem is that I've tried to use transfer with other address than "this", and I'm having the same issue – Adam Boudjemaa Dec 19 '18 at 10:09
• @Aboudjem The first argument to the transfer function is the destination address of the token transfer, not the source. The source address of the token transfer is the person or smart contract calling the transfer function. This causes the RES contract to try to transfer its own tokens, which I assume it does not have. Changing the first parameter of .transfer( only changes the destination address. This does not matter because the problem is that the source address (the RES contract) does not have enough tokens. – Jesse Busman Dec 19 '18 at 11:06
• thank you very much Jesse, I tried to approve by adding "token.approve(this, 100);" and then token.transferFrom, its working with 0 as amount but I'm still having the same issue when I add more than 0, I don't have "approveAndCall' method. – Adam Boudjemaa Dec 19 '18 at 14:03
• Don't add the approve call to the RES contract. Whoever calls requestReservation should call approve first. – Jesse Busman Dec 19 '18 at 14:43
• thank you for your patience, I'm kinda of lost, I will try to find a way to call approve outside my RES contract. – Adam Boudjemaa Dec 19 '18 at 15:05