Here is my solidity
interface IERC20 {
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
}
interface V2 {
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
}
pragma solidity ^0.5.17;
contract tokenSales {
//string public name = "EthSwap Instant Exchange";
// IERC20 public token;
// V2 public rgp;
address token = 0x87e9D87f85e80D79A77067A090F0748241892F74;
address rgp = 0x153Eef8365e8F4ae62aC99b6C84520f81F572827;
address owner;
uint public price;
uint256 public tokensSold;
uint256 public decimals;
event sold(address account, uint price, address token);
modifier onlyOwner() {
require(
msg.sender == owner,
"RGP Token: Caller is not the Owner"
);
_;
}
constructor(uint _price) public payable{
owner == msg.sender;
price = _price;
// SMC: 0xDA0bab807633f07f013f94DD0E6A4F96F8742B53
}
function() external payable{
buyTokens();
msg.value;
}
// Guards against integer overflows
function mul(uint x, uint y) public pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
}
//uint tokens = contribution.mul(multiplier).div(TOKEN_PRICE);
//tokenAllocations[investor] = tokenAllocations[investor].add(tokens);
//tokensSold = tokensSold.add(tokens);
function setBUSDCPrice(uint _price) public onlyOwner {
price = _price;
}
function sendCollectedBUSDC (address payable _recipient)
external
onlyOwner
{
if (address(this).balance > 0) {
_recipient.transfer(address(this).balance);
}
}
function buyTokens() public payable {
//CHECK FOR INPUT BALLANCE
require(msg.value > 0, "RGP: INSUFFICIENT INPUT BALLANCE, YOU NEED TO SEND SOME BUSDT");
//CALCULATE THE AMOUNT OF TOKEN TO PURCHASE
uint256 tokensToBuy = mul(msg.value, uint256(10) ** IERC20(token).decimals()) / mul(price, uint256(10) ** V2(rgp).decimals());
//ALLOWANCE FOR BOTH ADDRESS(THIS) AND MSG.SENDER
V2(rgp).allowance(msg.sender, address(this));
IERC20(token).allowance(address(this), msg.sender);
//REQUIREMENT FOR ALLOWANCE
tokensToBuy <= V2(rgp).allowance(address(this), msg.sender); // "RGP: CHECK THE TOKEN ALLOWANCE OF ADMIN";
msg.value <= IERC20(token).allowance(msg.sender, address(this)); // "RGP: CHECK THE TOKEN BALANCE OF BUYER";
//APPROVE FOR BOTH MSG.SENDER AND ADDRESS(THIS)
V2(rgp).approve(msg.sender, tokensToBuy);
IERC20(token).approve(address(this), msg.value);
//TRANSFER FROM MSG.SENDER TO ADDRESS(THIS)
IERC20(token).transferFrom(msg.sender, address(this), msg.value);
//CHECK FOR BALANCE OF ADMIN
uint256 rgpBalance = V2(rgp).balanceOf(address(this));
//REQUIRE THAT THE BALANCE APPROVED IS GREATER THAN THE TOKENS TO BUY.
require(rgpBalance >= tokensToBuy, "RGP: NOT ENOUGH TOKEN IN THE RESERVE");
//TRANSFER FROM RGP TO MSG.SENDER
V2(rgp).transferFrom(address(this), msg.sender, tokensToBuy);
//REDUCE THE ALLOWANCE OF BOTH PARTIES
IERC20(token).allowance(msg.sender, address(this)) + msg.value;
V2(rgp).allowance(address(this), msg.sender) + tokensToBuy;
//INCREASE THE ALLOWANCE OF BOTH PARTIES.
IERC20(token).allowance(msg.sender, address(this)) + msg.value;
V2(rgp).allowance(address(this), msg.sender) + tokensToBuy;
//
tokensSold += msg.value;
emit sold(msg.sender, msg.value * price, address(token));
}
function endSale() public onlyOwner{
// Send unsold tokens to the owner.
require(V2(rgp).transfer(owner, address(this).balance), "RGP: Sales ended.");
require(IERC20(token).transfer(owner, address(this).balance), "RGP: Sales ended.");
msg.sender.transfer(address(this).balance);
}
}
Deployed to ropsten "HERE"
The token address "TOKEN ADDRESS".
Please I have been on this for some days trying to figure out what wrong but I couldn't I have checked related issues on this platform and others still the same, I actually taught it was stress so I decided to take some time out and came back still can't figure it out.
I test on remix it deducts ether from msg.sender and did not credit to smart contract address and as well msg.sender did not receive token.
_amount1 * 10 * decimals / _amount1 / price
, mathematically is equivalent to10 * decimals / price
. Using approve+transferFrom doesn't work like you seems to be expecting. To accept ether payment you should usemsg.amount
. I'd suggest to read some tutorial or book.