status-security/external-reviews/paraswap/contracts/Partner.sol

290 lines
7.8 KiB
Solidity

pragma solidity 0.7.5;
contract Partner is Ownable, IPartner {
using SafeMath for uint256;
enum ChangeType { _, FEE, WALLET, SLIPPAGE }
struct ChangeRequest {
uint256 fee;
address payable wallet;
bool slippageToUser;
bool completed;
uint256 requestedBlockNumber;
}
mapping(uint256 => ChangeRequest) private _typeVsChangeRequest;
string private _referralId;
address payable private _feeWallet;
//It should be in basis points. For 1% it should be 100
uint256 private _fee;
//Paraswap share in the fee. For 20% it should 2000
//It means 20% of 1% fee charged
uint256 private _paraswapShare;
//Partner share in the fee. For 80% it should be 8000
uint256 private _partnerShare;
//Number of blocks after which change request can be fulfilled
uint256 private _timelock;
uint256 private _maxFee;
//Whether positive slippage will go to user
bool private _positiveSlippageToUser;
bool private _noPositiveSlippage;
event FeeWalletChanged(address indexed feeWallet);
event FeeChanged(uint256 fee);
event ChangeRequested(
ChangeType changeType,
uint256 fee,
address wallet,
bool positiveSlippageToUser,
uint256 requestedBlockNumber
);
event ChangeRequestCancelled(
ChangeType changeType,
uint256 fee,
address wallet,
bool positiveSlippageToUser,
uint256 requestedBlockNumber
);
event ChangeRequestFulfilled(
ChangeType changeType,
uint256 fee,
address wallet,
bool positiveSlippageToUser,
uint256 requestedBlockNumber,
uint256 fulfilledBlockNumber
);
constructor(
string memory referralId,
address payable feeWallet,
uint256 fee,
uint256 paraswapShare,
uint256 partnerShare,
address owner,
uint256 timelock,
uint256 maxFee,
bool positiveSlippageToUser,
bool noPositiveSlippage
)
public
{
_referralId = referralId;
_feeWallet = feeWallet;
_fee = fee;
_paraswapShare = paraswapShare;
_partnerShare = partnerShare;
_timelock = timelock;
_maxFee = maxFee;
_positiveSlippageToUser = positiveSlippageToUser;
_noPositiveSlippage = noPositiveSlippage;
transferOwnership(owner);
}
function getReferralId() external view returns(string memory) {
return _referralId;
}
function getFeeWallet() external view returns(address payable) {
return _feeWallet;
}
function getFee() external view returns(uint256) {
return _fee;
}
function getPartnerShare() external view returns(uint256) {
return _partnerShare;
}
function getParaswapShare() external view returns(uint256) {
return _paraswapShare;
}
function getTimeLock() external view returns(uint256) {
return _timelock;
}
function getMaxFee() external view returns(uint256) {
return _maxFee;
}
function getNoPositiveSlippage() external view returns(bool) {
return _noPositiveSlippage;
}
function getPositiveSlippageToUser() external view returns(bool) {
return _positiveSlippageToUser;
}
function getPartnerInfo() external override view returns(
address payable feeWallet,
uint256 fee,
uint256 partnerShare,
uint256 paraswapShare,
bool positiveSlippageToUser,
bool noPositiveSlippage
)
{
return(
_feeWallet,
_fee,
_partnerShare,
_paraswapShare,
_positiveSlippageToUser,
_noPositiveSlippage
);
}
function getChangeRequest(
ChangeType changeType
)
external
view
returns(
uint256,
address,
bool,
uint256
)
{
ChangeRequest memory changeRequest = _typeVsChangeRequest[uint256(changeType)];
return(
changeRequest.fee,
changeRequest.wallet,
changeRequest.completed,
changeRequest.requestedBlockNumber
);
}
function changeFeeRequest(uint256 fee) external onlyOwner {
require(fee <= _maxFee, "Invalid fee passed!!");
ChangeRequest storage changeRequest = _typeVsChangeRequest[uint256(ChangeType.FEE)];
require(
changeRequest.requestedBlockNumber == 0 || changeRequest.completed,
"Previous fee change request pending"
);
changeRequest.fee = fee;
changeRequest.requestedBlockNumber = block.number;
changeRequest.completed = false;
emit ChangeRequested(
ChangeType.FEE,
fee,
address(0),
false,
block.number
);
}
function changeWalletRequest(address payable wallet) external onlyOwner {
require(wallet != address(0), "Invalid fee wallet passed!!");
ChangeRequest storage changeRequest = _typeVsChangeRequest[uint256(ChangeType.WALLET)];
require(
changeRequest.requestedBlockNumber == 0 || changeRequest.completed,
"Previous fee change request pending"
);
changeRequest.wallet = wallet;
changeRequest.requestedBlockNumber = block.number;
changeRequest.completed = false;
emit ChangeRequested(
ChangeType.WALLET,
0,
wallet,
false,
block.number
);
}
function changePositiveSlippageToUser(bool slippageToUser) external onlyOwner {
ChangeRequest storage changeRequest = _typeVsChangeRequest[uint256(ChangeType.SLIPPAGE)];
require(
changeRequest.requestedBlockNumber == 0 || changeRequest.completed,
"Previous slippage change request pending"
);
changeRequest.slippageToUser = slippageToUser;
changeRequest.requestedBlockNumber = block.number;
changeRequest.completed = false;
emit ChangeRequested(
ChangeType.SLIPPAGE,
0,
address(0),
slippageToUser,
block.number
);
}
function confirmChangeRequest(ChangeType changeType) external onlyOwner {
ChangeRequest storage changeRequest = _typeVsChangeRequest[uint256(changeType)];
require(
changeRequest.requestedBlockNumber > 0 && !changeRequest.completed,
"Invalid request"
);
require(
changeRequest.requestedBlockNumber.add(_timelock) <= block.number,
"Request is in waiting period"
);
changeRequest.completed = true;
if(changeType == ChangeType.FEE) {
_fee = changeRequest.fee;
}
else if(changeType == ChangeType.WALLET) {
_feeWallet = changeRequest.wallet;
}
else {
_positiveSlippageToUser = changeRequest.slippageToUser;
}
emit ChangeRequestFulfilled(
changeType,
changeRequest.fee,
changeRequest.wallet,
changeRequest.slippageToUser,
changeRequest.requestedBlockNumber,
block.number
);
}
function cancelChangeRequest(ChangeType changeType) external onlyOwner {
ChangeRequest storage changeRequest = _typeVsChangeRequest[uint256(changeType)];
require(
changeRequest.requestedBlockNumber > 0 && !changeRequest.completed,
"Invalid request"
);
changeRequest.completed = true;
emit ChangeRequestCancelled(
changeType,
changeRequest.fee,
changeRequest.wallet,
changeRequest.slippageToUser,
changeRequest.requestedBlockNumber
);
}
}