96 lines
2.8 KiB
Solidity
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)
|
|
);
|
|
}
|
|
}
|