Skip to content

Instantly share code, notes, and snippets.

@imyourm8
Last active January 25, 2021 11:27
Show Gist options
  • Save imyourm8/d2575c65d7482ed2091972be2b2dbdd0 to your computer and use it in GitHub Desktop.
Save imyourm8/d2575c65d7482ed2091972be2b2dbdd0 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: UNLICENSED
// File contracts/lib/IERC20.sol
pragma solidity 0.7.3;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File contracts/lib/Ownable.sol
pragma solidity 0.7.3;
abstract contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
address msgSender = msg.sender;
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == msg.sender, "Ownable: caller is not the owner");
_;
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
// File contracts/lib/DelegationProxy.sol
pragma solidity 0.7.3;
interface StakingNFT {
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function transferFrom(address from, address to, uint256 tokenId) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) external;
}
interface ValidatorShare {
function buyVoucher(uint256, uint256) external;
function withdrawRewards() external;
function sellVoucher(uint256, uint256) external;
function unstakeClaimTokens() external;
function getLiquidRewards(address user) external view returns (uint256);
}
interface ValidatorShare_New {
function buyVoucher(uint256, uint256) external returns(uint256);
function withdrawRewards() external;
function sellVoucher(uint256, uint256) external;
function unstakeClaimTokens() external;
function sellVoucher_new(uint256, uint256) external;
function unstakeClaimTokens_new(uint256) external;
}
interface IStakeManager {
function getValidatorContract(uint256 validatorId) external view returns (address);
function token() external view returns (IERC20);
function NFTContract() external view returns (StakingNFT);
}
contract DelegationProxy is Ownable {
uint256[] public validatorsList;
mapping(uint256 => bool) public validatorsLookup;
IStakeManager public stakeManager;
constructor(IStakeManager _stakeManager) {
require(_stakeManager != IStakeManager(0x0));
stakeManager = _stakeManager;
}
function getLiquidRewards(uint256 validatorId) public view returns(uint256) {
ValidatorShare delegationContract = ValidatorShare(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare(0x0));
return delegationContract.getLiquidRewards(address(this));
}
function withdrawTokens(address tokenAddress, uint256 amount) public onlyOwner {
IERC20(tokenAddress).transfer(owner(), amount);
}
function delegate(uint256[] memory validators, uint256[] memory amount, uint256 totalAmount) public onlyOwner {
require(validators.length == amount.length);
IERC20 token = stakeManager.token();
token.approve(address(stakeManager), totalAmount);
for (uint256 i = 0; i < validators.length; ++i) {
uint256 validatorId = validators[i];
if (!validatorsLookup[validatorId]) {
validatorsLookup[validatorId] = true;
validatorsList.push(validatorId);
}
ValidatorShare delegationContract = ValidatorShare(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare(0x0));
// buy voucher
delegationContract.buyVoucher(amount[i], 0);
}
}
function delegate_new(uint256[] memory validators, uint256[] memory amount, uint256 totalAmount) public onlyOwner {
require(validators.length == amount.length);
IERC20 token = stakeManager.token();
token.approve(address(stakeManager), totalAmount);
for (uint256 i = 0; i < validators.length; ++i) {
uint256 validatorId = validators[i];
if (!validatorsLookup[validatorId]) {
validatorsLookup[validatorId] = true;
validatorsList.push(validatorId);
}
ValidatorShare_New delegationContract = ValidatorShare_New(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare_New(0x0));
// buy voucher
delegationContract.buyVoucher(amount[i], 0);
}
}
function transferRewards(uint256[] memory validators) public onlyOwner {
IERC20 token = stakeManager.token();
StakingNFT nft = stakeManager.NFTContract();
uint256 tokenBalanceBefore = token.balanceOf(address(this));
for (uint256 i = 0; i < validators.length; ++i) {
uint256 validatorId = validators[i];
ValidatorShare delegationContract = ValidatorShare(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare(0x0));
delegationContract.withdrawRewards();
uint256 rewards = token.balanceOf(address(this)) - tokenBalanceBefore;
token.transfer(nft.ownerOf(validatorId), rewards);
}
}
function collectRewards(uint256[] memory validators) public onlyOwner {
for (uint256 i = 0; i < validators.length; ++i) {
uint256 validatorId = validators[i];
ValidatorShare delegationContract = ValidatorShare(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare(0x0));
delegationContract.withdrawRewards();
}
}
function sellVoucher(uint256 validatorId, uint256 claimAmount, uint256 maximumSharesToBurn) public onlyOwner {
ValidatorShare delegationContract = ValidatorShare(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare(0x0));
delegationContract.sellVoucher(claimAmount, maximumSharesToBurn);
}
function sellVoucher_new(uint256 validatorId, uint256 claimAmount, uint256 maximumSharesToBurn) public onlyOwner {
ValidatorShare_New delegationContract = ValidatorShare_New(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare_New(0x0));
delegationContract.sellVoucher_new(claimAmount, maximumSharesToBurn);
}
function unstakeClaimTokens(uint256 validatorId) public onlyOwner {
ValidatorShare delegationContract = ValidatorShare(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare(0x0));
delegationContract.unstakeClaimTokens();
}
function unstakeClaimTokens_new(uint256 validatorId, uint256 unbondNonce) public onlyOwner {
ValidatorShare_New delegationContract = ValidatorShare_New(stakeManager.getValidatorContract(validatorId));
require(delegationContract != ValidatorShare_New(0x0));
delegationContract.unstakeClaimTokens_new(unbondNonce);
}
function callAny(address target, bytes memory data) public onlyOwner {
(bool success, ) = target.call(data); /* bytes memory returnData */
require(success, "Call failed");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment