becrypto/contracts/BEBoxMall.sol
2022-01-27 19:13:37 +08:00

96 lines
2.8 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./HasSignature.sol";
contract BEBoxMall is Ownable, HasSignature {
using SafeERC20 for IERC20;
using Address for address;
event BEBoxPaid(
uint256 indexed boxId,
address indexed buyer,
uint256 boxType,
uint256 price,
address paymentToken
);
address public paymentReceivedAddress;
mapping(bytes => bool) public usedSignatures;
function setPaymentReceivedAddress(address _paymentReceivedAddress)
external
onlyOwner
{
require(_paymentReceivedAddress != address(0), 'payment received address can not be zero');
paymentReceivedAddress = _paymentReceivedAddress;
}
/**
* @dev BE box payment function
*/
function payForBoxWithSignature(
uint256 boxId,
uint256 _type,
address userAddress,
uint256 price,
address paymentErc20,
uint256 saltNonce,
bytes calldata signature
) external onlyOwner {
require(
!userAddress.isContract(),
"BEBoxPayment: Only user address is allowed to buy box"
);
require(_type > 0, "BEBoxPayment: Invalid box type");
require(price > 0, "BEBoxPayment: Invalid payment amount");
require(
!usedSignatures[signature],
"BEBoxPayment: signature used. please send another transaction with new signature"
);
bytes32 criteriaMessageHash = getMessageHash(
_type,
paymentErc20,
price,
saltNonce
);
checkSigner(userAddress, criteriaMessageHash, signature);
IERC20 paymentToken = IERC20(paymentErc20);
uint256 allowToPayAmount = paymentToken.allowance(
userAddress,
address(this)
);
require(
allowToPayAmount >= price,
"BEBoxPayment: Invalid token allowance"
);
// Transfer payment
paymentToken.safeTransferFrom(
userAddress,
paymentReceivedAddress,
price
);
usedSignatures[signature] = true;
// Emit payment event
emit BEBoxPaid(boxId, userAddress, _type, price, paymentErc20);
}
function getMessageHash(
uint256 _boxType,
address _paymentErc20,
uint256 _price,
uint256 _saltNonce
) public pure returns (bytes32) {
return
keccak256(
abi.encodePacked(_boxType, _paymentErc20, _price, _saltNonce)
);
}
}