文件 1 的 7:Address.sol
pragma solidity >=0.6.2 <0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 7:EIP3009.sol
pragma solidity ^0.7.0;
interface EIP3009 {
function transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
文件 3 的 7:IDAI.sol
pragma solidity ^0.7.0;
interface IDAI {
function permit(
address holder,
address spender,
uint256 nonce,
uint256 expiry,
bool allowed,
uint8 v,
bytes32 r,
bytes32 s
) external;
function transferFrom(
address src,
address dst,
uint256 wad
) external returns (bool);
}
文件 4 的 7:IERC20.sol
pragma solidity >=0.5.0;
interface IERC20 {
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
}
interface IERC20Mintable {
function mint(uint256 amount_) external;
function mint(address account_, uint256 ammount_) external;
}
文件 5 的 7:Ownable.sol
pragma solidity 0.7.5;
interface IOwnable {
function owner() external view returns (address);
function renounceManagement() external;
function pushManagement(address newOwner_) external;
function pullManagement() external;
}
contract Ownable is IOwnable {
address internal _owner;
address internal _newOwner;
event OwnershipPushed(
address indexed previousOwner,
address indexed newOwner
);
event OwnershipPulled(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
_owner = msg.sender;
emit OwnershipPushed(address(0), _owner);
}
function owner() public view override returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == msg.sender, 'Ownable: caller is not the owner');
_;
}
function renounceManagement() public virtual override onlyOwner {
emit OwnershipPushed(_owner, address(0));
_owner = address(0);
}
function pushManagement(address newOwner_)
public
virtual
override
onlyOwner
{
require(
newOwner_ != address(0),
'Ownable: new owner is the zero address'
);
emit OwnershipPushed(_owner, newOwner_);
_newOwner = newOwner_;
}
function pullManagement() public virtual override {
require(msg.sender == _newOwner, 'Ownable: must be new owner to pull');
emit OwnershipPulled(_owner, _newOwner);
_owner = _newOwner;
}
}
文件 6 的 7:SafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
文件 7 的 7:subscription.sol
pragma solidity 0.7.5;
import "./SafeMath.sol";
import "./Address.sol";
import "./IERC20.sol";
import "./Ownable.sol";
import "./EIP3009.sol";
import "./IDAI.sol";
contract subscription is Ownable{
using Address for address;
using SafeMath for uint256;
address public USDC;
address public USDT;
address public DAI;
uint256 public priceUSDC;
uint256 public priceUSDT;
uint256 public priceDAI;
uint256 public priceETH;
address private forward;
address private forwardUSA;
event Payment(
string currency,
uint256 amount,
string id,
address sender,
address forwardTo
);
constructor(
address _USDC,
address _USDT,
address _DAI,
address _forward,
address _forwardUSA,
uint256 _priceUSDC,
uint256 _priceUSDT,
uint256 _priceDAI,
uint256 _priceETH
){
USDC = _USDC;
USDT = _USDT;
DAI = _DAI;
forward = _forward;
forwardUSA = _forwardUSA;
priceUSDC = _priceUSDC;
priceUSDT = _priceUSDT;
priceDAI = _priceDAI;
priceETH = _priceETH;
}
function payUSDC(string memory _id, bool _world ) external returns(bool) {
address to = getTo(_world);
bool success = IERC20(USDC).transferFrom(msg.sender, to, priceUSDC);
require(success, "Dev: Token transfer failed");
emit Payment("USDC", priceUSDC, _id, msg.sender, to);
return true;
}
function payUSDCWithPermit(
string memory _id,
bool _world,
address _from,
address _to,
uint256 _value,
uint256 _validAfter,
uint256 _validBefore,
bytes32 _nonce,
uint8 _v,
bytes32 _r,
bytes32 _s
) external returns(bool){
address to = getTo(_world);
require(_value == priceUSDC ,"Wrong price");
EIP3009(USDC).transferWithAuthorization( _from, to, _value, _validAfter, _validBefore, _nonce, _v, _r, _s);
emit Payment("USDC", _value, _id, _from, to);
return true;
}
function payDAI(string memory _id, bool _world ) external returns(bool) {
address to = getTo(_world);
bool success = IERC20(DAI).transferFrom(msg.sender, to, priceDAI);
require(success, "Dev: Token transfer failed");
emit Payment("DAI", priceDAI, _id, msg.sender, to);
return true;
}
function payDAIWithPermit(
string memory _id,
bool _world,
address _holder,
address _spender,
uint256 _nonce,
uint256 _expiry,
bool _allowed,
uint8 _v,
bytes32 _r,
bytes32 _s
) external returns(bool) {
address to = getTo(_world);
IDAI(DAI).permit(_holder, _spender, _nonce, _expiry, _allowed, _v, _r, _s);
bool success = IDAI(DAI).transferFrom(_holder, to, priceDAI);
require(success, "Dev: Token transfer failed");
emit Payment("DAI", priceDAI, _id, _holder, to);
return true;
}
function payUSDT(string memory _id, bool _world) external returns(bool) {
address to = getTo(_world);
bool success = IERC20(USDT).transferFrom(msg.sender, to, priceUSDT);
require(success, "Dev: Token transfer failed");
emit Payment("USDT", priceUSDT, _id, msg.sender, to);
return true;
}
function payETH(string memory _id, bool _world) external payable returns(bool) {
address to = getTo(_world);
require(msg.value >= priceETH, "Dev: invalid amount");
(bool sent, bytes memory data) = to.call{value: msg.value}("");
require(sent, "Dev: Ether payment error");
emit Payment("ETH", msg.value, _id, msg.sender, to);
return true;
}
function setPriceUSDC(uint256 _price)external onlyOwner returns(bool) {
priceUSDC = _price;
return true;
}
function setPriceDAI(uint256 _price)external onlyOwner returns(bool) {
priceDAI = _price;
return true;
}
function setPriceUSDT(uint256 _price)external onlyOwner returns(bool) {
priceUSDT = _price;
return true;
}
function setPriceETH(uint256 _price)external onlyOwner returns(bool) {
priceETH = _price;
return true;
}
function setForward(address _forward) external onlyOwner returns(bool) {
forward = _forward;
return true;
}
function setForwardUSA(address _forwardUSA) external onlyOwner returns(bool) {
forwardUSA = _forwardUSA;
return true;
}
function recoverEther(uint256 _amount) external onlyOwner returns(bool){
payable(owner()).transfer(_amount);
return true;
}
function recoverERC20(address _tokenAddress, uint256 _amount) external onlyOwner returns(bool){
IERC20 token = IERC20(_tokenAddress);
token.transfer(owner(), _amount);
return true;
}
function getTo(bool _world) internal view returns(address){
address to;
if (_world) {
to = forward;
} else {
to = forwardUSA;
}
return to;
}
}
{
"compilationTarget": {
"subscription.sol": "subscription"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_USDC","type":"address"},{"internalType":"address","name":"_USDT","type":"address"},{"internalType":"address","name":"_DAI","type":"address"},{"internalType":"address","name":"_forward","type":"address"},{"internalType":"address","name":"_forwardUSA","type":"address"},{"internalType":"uint256","name":"_priceUSDC","type":"uint256"},{"internalType":"uint256","name":"_priceUSDT","type":"uint256"},{"internalType":"uint256","name":"_priceDAI","type":"uint256"},{"internalType":"uint256","name":"_priceETH","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipPushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"currency","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"id","type":"string"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"forwardTo","type":"address"}],"name":"Payment","type":"event"},{"inputs":[],"name":"DAI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_id","type":"string"},{"internalType":"bool","name":"_world","type":"bool"}],"name":"payDAI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_id","type":"string"},{"internalType":"bool","name":"_world","type":"bool"},{"internalType":"address","name":"_holder","type":"address"},{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_expiry","type":"uint256"},{"internalType":"bool","name":"_allowed","type":"bool"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"payDAIWithPermit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_id","type":"string"},{"internalType":"bool","name":"_world","type":"bool"}],"name":"payETH","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"_id","type":"string"},{"internalType":"bool","name":"_world","type":"bool"}],"name":"payUSDC","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_id","type":"string"},{"internalType":"bool","name":"_world","type":"bool"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_validAfter","type":"uint256"},{"internalType":"uint256","name":"_validBefore","type":"uint256"},{"internalType":"bytes32","name":"_nonce","type":"bytes32"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"payUSDCWithPermit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_id","type":"string"},{"internalType":"bool","name":"_world","type":"bool"}],"name":"payUSDT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"priceDAI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceUSDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceUSDT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pullManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"pushManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverERC20","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverEther","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_forward","type":"address"}],"name":"setForward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_forwardUSA","type":"address"}],"name":"setForwardUSA","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPriceDAI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPriceETH","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPriceUSDC","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPriceUSDT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]