start
This commit is contained in:
commit
b8464b39f2
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
node_modules
|
||||
.env
|
||||
coverage
|
||||
coverage.json
|
||||
typechain
|
||||
typechain-types
|
||||
|
||||
# Hardhat files
|
||||
cache
|
||||
artifacts
|
||||
|
19
.prettierrc
Normal file
19
.prettierrc
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.sol",
|
||||
"options": {
|
||||
"printWidth": 120,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"singleQuote": false,
|
||||
"bracketSpacing": true
|
||||
}
|
||||
},
|
||||
{"files": "*.js", "options": {
|
||||
"bracketSpacing": true,
|
||||
"printWidth": 120
|
||||
}}
|
||||
],
|
||||
"bracketSpacing": true
|
||||
}
|
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Proposal 45
|
||||
|
||||
Create airdrop with Sablier streams and snapshot
|
||||
|
||||
Deploy: npx hardhat run --network mainnet script/deploy.js
|
||||
|
||||
Tests: npm run test
|
||||
|
||||
Dont forget to fill env file
|
273
contracts/Airdrop.sol
Normal file
273
contracts/Airdrop.sol
Normal file
@ -0,0 +1,273 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity =0.5.17;
|
||||
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./interfaces/IERC20.sol";
|
||||
import "./interfaces/IGovernance.sol";
|
||||
import "./libraries/SafeERC20.sol";
|
||||
import "./ReentrancyGuard.sol";
|
||||
import "./CarefulMath.sol";
|
||||
|
||||
import "./interfaces/ISablierAirdrop.sol";
|
||||
import "./libraries/Types.sol";
|
||||
|
||||
contract SablierAirdrop is ISablierAirdrop, ReentrancyGuard, CarefulMath {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/*** Storage Properties ***/
|
||||
|
||||
address public constant tornadoGovernance = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce;
|
||||
IERC20 public constant torn = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C);
|
||||
|
||||
/**
|
||||
* @notice Counter for new stream ids.
|
||||
*/
|
||||
uint256 public nextStreamId;
|
||||
|
||||
/**
|
||||
* @notice The stream objects identifiable by their unsigned integer ids.
|
||||
*/
|
||||
mapping(uint256 => Types.Stream) private streams;
|
||||
|
||||
/*** Modifiers ***/
|
||||
|
||||
/**
|
||||
* @dev Throws if the caller is not the recipient of the stream.
|
||||
*/
|
||||
modifier onlyRecipient(uint256 streamId) {
|
||||
require(msg.sender == streams[streamId].recipient, "caller is not the recipient of the stream");
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Throws if the caller is not Tornado Cash Governance contract
|
||||
*/
|
||||
modifier onlyGovernance() {
|
||||
require(msg.sender == tornadoGovernance, "caller is not governance");
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Throws if the provided id does not point to a valid stream.
|
||||
*/
|
||||
modifier streamExists(uint256 streamId) {
|
||||
require(streams[streamId].isEntity, "stream does not exist");
|
||||
_;
|
||||
}
|
||||
|
||||
/*** Contract Logic Starts Here */
|
||||
|
||||
constructor() public {
|
||||
nextStreamId = 1;
|
||||
}
|
||||
|
||||
/*** View Functions ***/
|
||||
|
||||
/**
|
||||
* @notice Returns the stream with all its properties.
|
||||
* @dev Throws if the id does not point to a valid stream.
|
||||
* @param streamId The id of the stream to query.
|
||||
* @return The stream object.
|
||||
*/
|
||||
function getStream(
|
||||
uint256 streamId
|
||||
)
|
||||
external
|
||||
view
|
||||
streamExists(streamId)
|
||||
returns (
|
||||
address recipient,
|
||||
uint256 deposit,
|
||||
uint256 startTime,
|
||||
uint256 stopTime,
|
||||
uint256 remainingBalance,
|
||||
uint256 ratePerSecond
|
||||
)
|
||||
{
|
||||
recipient = streams[streamId].recipient;
|
||||
deposit = streams[streamId].deposit;
|
||||
startTime = streams[streamId].startTime;
|
||||
stopTime = streams[streamId].stopTime;
|
||||
remainingBalance = streams[streamId].remainingBalance;
|
||||
ratePerSecond = streams[streamId].ratePerSecond;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Returns either the delta in seconds between `block.timestamp` and `startTime` or
|
||||
* between `stopTime` and `startTime, whichever is smaller. If `block.timestamp` is before
|
||||
* `startTime`, it returns 0.
|
||||
* @dev Throws if the id does not point to a valid stream.
|
||||
* @param streamId The id of the stream for which to query the delta.
|
||||
* @return The time delta in seconds.
|
||||
*/
|
||||
function deltaOf(uint256 streamId) public view streamExists(streamId) returns (uint256 delta) {
|
||||
Types.Stream memory stream = streams[streamId];
|
||||
if (block.timestamp <= stream.startTime) return 0;
|
||||
if (block.timestamp < stream.stopTime) return block.timestamp - stream.startTime;
|
||||
return stream.stopTime - stream.startTime;
|
||||
}
|
||||
|
||||
struct BalanceOfLocalVars {
|
||||
MathError mathErr;
|
||||
uint256 recipientBalance;
|
||||
uint256 withdrawalAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Returns the available funds for the given stream id and address.
|
||||
* @dev Throws if the id does not point to a valid stream.
|
||||
* @param streamId The id of the stream for which to query the balance.
|
||||
* @param who The address for which to query the balance.
|
||||
* @return The total funds allocated to `who` as uint256.
|
||||
*/
|
||||
function balanceOf(uint256 streamId, address who) public view streamExists(streamId) returns (uint256 balance) {
|
||||
Types.Stream memory stream = streams[streamId];
|
||||
BalanceOfLocalVars memory vars;
|
||||
|
||||
uint256 delta = deltaOf(streamId);
|
||||
(vars.mathErr, vars.recipientBalance) = mulUInt(delta, stream.ratePerSecond);
|
||||
require(vars.mathErr == MathError.NO_ERROR, "recipient balance calculation error");
|
||||
|
||||
/*
|
||||
* If the stream `balance` does not equal `deposit`, it means there have been withdrawals.
|
||||
* We have to subtract the total amount withdrawn from the amount of money that has been
|
||||
* streamed until now.
|
||||
*/
|
||||
if (stream.deposit > stream.remainingBalance) {
|
||||
(vars.mathErr, vars.withdrawalAmount) = subUInt(stream.deposit, stream.remainingBalance);
|
||||
assert(vars.mathErr == MathError.NO_ERROR);
|
||||
(vars.mathErr, vars.recipientBalance) = subUInt(vars.recipientBalance, vars.withdrawalAmount);
|
||||
/* `withdrawalAmount` cannot and should not be bigger than `recipientBalance`. */
|
||||
assert(vars.mathErr == MathError.NO_ERROR);
|
||||
}
|
||||
|
||||
if (who == stream.recipient) return vars.recipientBalance;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** Public Effects & Interactions Functions ***/
|
||||
|
||||
struct CreateStreamLocalVars {
|
||||
MathError mathErr;
|
||||
uint256 duration;
|
||||
uint256 ratePerSecond;
|
||||
}
|
||||
|
||||
function createAirdrop(
|
||||
Types.Recipient[] memory recipients,
|
||||
uint256 startTime,
|
||||
uint256 stopTime
|
||||
) public onlyGovernance returns (bool) {
|
||||
uint256 airdropDuration = stopTime - startTime;
|
||||
CreateStreamLocalVars memory vars;
|
||||
|
||||
for (uint256 i = 0; i < recipients.length; i++) {
|
||||
uint256 normalizedDeposit = recipients[i].deposit - (recipients[i].deposit % airdropDuration);
|
||||
address recipientAddr = recipients[i].addr;
|
||||
uint256 recipientInitialLockedBalance = recipients[i].initialLockedBalance;
|
||||
|
||||
/* Without this, the rate per second would be zero. */
|
||||
require(normalizedDeposit >= airdropDuration, "deposit smaller than time delta");
|
||||
|
||||
(vars.mathErr, vars.ratePerSecond) = divUInt(normalizedDeposit, airdropDuration);
|
||||
/* `divUInt` can only return MathError.DIVISION_BY_ZERO but we know `duration` is not zero. */
|
||||
assert(vars.mathErr == MathError.NO_ERROR);
|
||||
|
||||
/* Create and store the stream object. */
|
||||
uint256 streamId = nextStreamId;
|
||||
streams[streamId] = Types.Stream({
|
||||
remainingBalance: normalizedDeposit,
|
||||
deposit: normalizedDeposit,
|
||||
initialLockedBalance: recipientInitialLockedBalance,
|
||||
isEntity: true,
|
||||
ratePerSecond: vars.ratePerSecond,
|
||||
recipient: recipientAddr,
|
||||
startTime: startTime,
|
||||
stopTime: stopTime
|
||||
});
|
||||
|
||||
/* Increment the next stream id. */
|
||||
(vars.mathErr, nextStreamId) = addUInt(nextStreamId, uint256(1));
|
||||
require(vars.mathErr == MathError.NO_ERROR, "next stream id calculation error");
|
||||
|
||||
emit CreateStream(
|
||||
streamId,
|
||||
recipientAddr,
|
||||
normalizedDeposit,
|
||||
recipientInitialLockedBalance,
|
||||
startTime,
|
||||
stopTime
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Withdraws from the contract to the recipient's account.
|
||||
* @dev Throws if the id does not point to a valid stream.
|
||||
* Throws if the caller is not the sender or the recipient of the stream.
|
||||
* Throws if the amount exceeds the available balance.
|
||||
* Throws if there is a token transfer failure.
|
||||
* @param streamId The id of the stream to withdraw tokens from.
|
||||
* @param amount The amount of tokens to withdraw.
|
||||
*/
|
||||
function withdrawFromStream(
|
||||
uint256 streamId,
|
||||
uint256 amount
|
||||
) external nonReentrant streamExists(streamId) onlyRecipient(streamId) returns (bool) {
|
||||
require(amount > 0, "amount is zero");
|
||||
Types.Stream memory stream = streams[streamId];
|
||||
|
||||
uint256 recipientLockedBalance = IGovernance(tornadoGovernance).lockedBalance(stream.recipient);
|
||||
require(recipientLockedBalance >= stream.initialLockedBalance, "not enough locked tokens in governance");
|
||||
|
||||
uint256 balance = balanceOf(streamId, stream.recipient);
|
||||
require(balance >= amount, "amount exceeds the available balance");
|
||||
|
||||
MathError mathErr;
|
||||
(mathErr, streams[streamId].remainingBalance) = subUInt(stream.remainingBalance, amount);
|
||||
/**
|
||||
* `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know that `remainingBalance` is at least
|
||||
* as big as `amount`.
|
||||
*/
|
||||
assert(mathErr == MathError.NO_ERROR);
|
||||
|
||||
if (streams[streamId].remainingBalance == 0) delete streams[streamId];
|
||||
|
||||
torn.safeTransfer(stream.recipient, amount);
|
||||
emit WithdrawFromStream(streamId, stream.recipient, amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Cancels the stream and transfers the tokens back (remaining and unclaimed).
|
||||
* @dev Throws if the id does not point to a valid stream.
|
||||
* Throws if the caller is not the sender of the stream.
|
||||
* Throws if there is a token transfer failure.
|
||||
* @param streamId The id of the stream to cancel.
|
||||
* @return bool true=success, otherwise false.
|
||||
*/
|
||||
function cancelStream(uint256 streamId) external nonReentrant streamExists(streamId) onlyGovernance returns (bool) {
|
||||
Types.Stream memory stream = streams[streamId];
|
||||
uint256 remainingBalance = stream.remainingBalance;
|
||||
|
||||
delete streams[streamId];
|
||||
|
||||
if (remainingBalance > 0) torn.safeTransfer(tornadoGovernance, remainingBalance);
|
||||
|
||||
emit CancelStream(streamId, stream.recipient, remainingBalance);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Cancels airdrop and withdraw all unclaimed tokens back to governance.
|
||||
* @dev Throws if there is a token transfer failure.
|
||||
* @return bool true=success, otherwise false.
|
||||
*/
|
||||
function cancelAirdrop() external onlyGovernance returns (bool) {
|
||||
torn.safeTransfer(tornadoGovernance, torn.balanceOf(address(this)));
|
||||
return true;
|
||||
}
|
||||
}
|
84
contracts/CarefulMath.sol
Normal file
84
contracts/CarefulMath.sol
Normal file
@ -0,0 +1,84 @@
|
||||
pragma solidity >=0.5.17;
|
||||
|
||||
/**
|
||||
* @title Careful Math
|
||||
* @author Compound
|
||||
* @notice Derived from OpenZeppelin's SafeMath library
|
||||
* https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol
|
||||
*/
|
||||
contract CarefulMath {
|
||||
/**
|
||||
* @dev Possible error codes that we can return
|
||||
*/
|
||||
enum MathError {
|
||||
NO_ERROR,
|
||||
DIVISION_BY_ZERO,
|
||||
INTEGER_OVERFLOW,
|
||||
INTEGER_UNDERFLOW
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Multiplies two numbers, returns an error on overflow.
|
||||
*/
|
||||
function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {
|
||||
if (a == 0) {
|
||||
return (MathError.NO_ERROR, 0);
|
||||
}
|
||||
|
||||
uint c = a * b;
|
||||
|
||||
if (c / a != b) {
|
||||
return (MathError.INTEGER_OVERFLOW, 0);
|
||||
} else {
|
||||
return (MathError.NO_ERROR, c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two numbers, truncating the quotient.
|
||||
*/
|
||||
function divUInt(uint a, uint b) internal pure returns (MathError, uint) {
|
||||
if (b == 0) {
|
||||
return (MathError.DIVISION_BY_ZERO, 0);
|
||||
}
|
||||
|
||||
return (MathError.NO_ERROR, a / b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).
|
||||
*/
|
||||
function subUInt(uint a, uint b) internal pure returns (MathError, uint) {
|
||||
if (b <= a) {
|
||||
return (MathError.NO_ERROR, a - b);
|
||||
} else {
|
||||
return (MathError.INTEGER_UNDERFLOW, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two numbers, returns an error on overflow.
|
||||
*/
|
||||
function addUInt(uint a, uint b) internal pure returns (MathError, uint) {
|
||||
uint c = a + b;
|
||||
|
||||
if (c >= a) {
|
||||
return (MathError.NO_ERROR, c);
|
||||
} else {
|
||||
return (MathError.INTEGER_OVERFLOW, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev add a and b and then subtract c
|
||||
*/
|
||||
function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {
|
||||
(MathError err0, uint sum) = addUInt(a, b);
|
||||
|
||||
if (err0 != MathError.NO_ERROR) {
|
||||
return (err0, 0);
|
||||
}
|
||||
|
||||
return subUInt(sum, c);
|
||||
}
|
||||
}
|
36
contracts/Proposal.sol
Normal file
36
contracts/Proposal.sol
Normal file
@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.9;
|
||||
|
||||
import "./libraries/Types.sol";
|
||||
import "./interfaces/IERC20.sol";
|
||||
import { ISablierAirdrop } from "./interfaces/ISablierAirdrop.sol"; // copied from proposal 28
|
||||
|
||||
contract Proposal {
|
||||
IERC20 public constant torn = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C);
|
||||
ISablierAirdrop public immutable airdrop;
|
||||
uint256 public constant airdropDuration = 180 days;
|
||||
Types.Recipient[] public recipients;
|
||||
|
||||
constructor(address _airdropContract) {
|
||||
Types.Recipient[1] memory _recipients = [
|
||||
Types.Recipient({
|
||||
addr: 0xeb3E49Af2aB5D5D0f83A9289cF5a34d9e1f6C5b4,
|
||||
deposit: 1000 ether,
|
||||
initialLockedBalance: 1000 ether
|
||||
})
|
||||
];
|
||||
airdrop = ISablierAirdrop(_airdropContract);
|
||||
for (uint256 i = 0; i < _recipients.length; i++) {
|
||||
recipients.push(_recipients[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function executeProposal() external {
|
||||
torn.transfer(address(airdrop), 1000000 ether);
|
||||
|
||||
require(recipients[0].addr != address(0), "zero");
|
||||
uint256 startTime = block.timestamp;
|
||||
uint256 endTime = startTime + airdropDuration;
|
||||
airdrop.createAirdrop(recipients, startTime, endTime);
|
||||
}
|
||||
}
|
38
contracts/ReentrancyGuard.sol
Normal file
38
contracts/ReentrancyGuard.sol
Normal file
@ -0,0 +1,38 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @dev Contract module that helps prevent reentrant calls to a function.
|
||||
*
|
||||
* Inheriting from `ReentrancyGuard` will make the `nonReentrant` modifier
|
||||
* available, which can be aplied to functions to make sure there are no nested
|
||||
* (reentrant) calls to them.
|
||||
*
|
||||
* Note that because there is a single `nonReentrant` guard, functions marked as
|
||||
* `nonReentrant` may not call one another. This can be worked around by making
|
||||
* those functions `private`, and then adding `external` `nonReentrant` entry
|
||||
* points to them.
|
||||
*/
|
||||
contract ReentrancyGuard {
|
||||
/// @dev counter to allow mutex lock with only one SSTORE operation
|
||||
uint256 private _guardCounter;
|
||||
|
||||
constructor() internal {
|
||||
// The counter starts at one to prevent changing it from zero to a non-zero
|
||||
// value, which is a more expensive operation.
|
||||
_guardCounter = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Prevents a contract from calling itself, directly or indirectly.
|
||||
* Calling a `nonReentrant` function from another `nonReentrant`
|
||||
* function is not supported. It is possible to prevent this from happening
|
||||
* by making the `nonReentrant` function external, and make it call a
|
||||
* `private` function that does the actual work.
|
||||
*/
|
||||
modifier nonReentrant() {
|
||||
_guardCounter += 1;
|
||||
uint256 localCounter = _guardCounter;
|
||||
_;
|
||||
require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call");
|
||||
}
|
||||
}
|
77
contracts/interfaces/IERC20.sol
Normal file
77
contracts/interfaces/IERC20.sol
Normal file
@ -0,0 +1,77 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
|
||||
* the optional functions; to access them see `ERC20Detailed`.
|
||||
*/
|
||||
interface IERC20 {
|
||||
/**
|
||||
* @dev Returns the amount of tokens in existence.
|
||||
*/
|
||||
function totalSupply() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the amount of tokens owned by `account`.
|
||||
*/
|
||||
function balanceOf(address account) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Moves `amount` tokens from the caller's account to `recipient`.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* Emits a `Transfer` event.
|
||||
*/
|
||||
function transfer(address recipient, uint256 amount) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Returns the remaining number of tokens that `spender` will be
|
||||
* allowed to spend on behalf of `owner` through `transferFrom`. This is
|
||||
* zero by default.
|
||||
*
|
||||
* This value changes when `approve` or `transferFrom` are called.
|
||||
*/
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* > Beware that changing an allowance with this method brings the risk
|
||||
* that someone may use both the old and the new allowance by unfortunate
|
||||
* transaction ordering. One possible solution to mitigate this race
|
||||
* condition is to first reduce the spender's allowance to 0 and set the
|
||||
* desired value afterwards:
|
||||
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
|
||||
*
|
||||
* Emits an `Approval` event.
|
||||
*/
|
||||
function approve(address spender, uint256 amount) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Moves `amount` tokens from `sender` to `recipient` using the
|
||||
* allowance mechanism. `amount` is then deducted from the caller's
|
||||
* allowance.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* Emits a `Transfer` event.
|
||||
*/
|
||||
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `value` tokens are moved from one account (`from`) to
|
||||
* another (`to`).
|
||||
*
|
||||
* Note that `value` may be zero.
|
||||
*/
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
|
||||
* a call to `approve`. `value` is the new allowance.
|
||||
*/
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
}
|
6
contracts/interfaces/IGovernance.sol
Normal file
6
contracts/interfaces/IGovernance.sol
Normal file
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
interface IGovernance {
|
||||
function lockedBalance(address staker) external view returns (uint256);
|
||||
}
|
56
contracts/interfaces/ISablierAirdrop.sol
Normal file
56
contracts/interfaces/ISablierAirdrop.sol
Normal file
@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity >=0.5.17;
|
||||
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../libraries/Types.sol";
|
||||
|
||||
interface ISablierAirdrop {
|
||||
/**
|
||||
* @notice Emits when a stream is successfully created.
|
||||
*/
|
||||
event CreateStream(
|
||||
uint256 indexed streamId,
|
||||
address indexed recipient,
|
||||
uint256 deposit,
|
||||
uint256 initialLockedBalance,
|
||||
uint256 startTime,
|
||||
uint256 stopTime
|
||||
);
|
||||
|
||||
/**
|
||||
* @notice Emits when the recipient of a stream withdraws a portion or all their pro rata share of the stream.
|
||||
*/
|
||||
event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount);
|
||||
|
||||
/**
|
||||
* @notice Emits when a stream is successfully cancelled and tokens are transferred back on a pro rata basis.
|
||||
*/
|
||||
event CancelStream(uint256 indexed streamId, address indexed recipient, uint256 remainingBalance);
|
||||
|
||||
function balanceOf(uint256 streamId, address who) external view returns (uint256 balance);
|
||||
|
||||
function getStream(
|
||||
uint256 streamId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
address recipient,
|
||||
uint256 deposit,
|
||||
uint256 startTime,
|
||||
uint256 stopTime,
|
||||
uint256 remainingBalance,
|
||||
uint256 ratePerSecond
|
||||
);
|
||||
|
||||
function createAirdrop(
|
||||
Types.Recipient[] calldata recipients,
|
||||
uint256 startTime,
|
||||
uint256 stopTime
|
||||
) external returns (bool);
|
||||
|
||||
function withdrawFromStream(uint256 streamId, uint256 funds) external returns (bool);
|
||||
|
||||
function cancelStream(uint256 streamId) external returns (bool);
|
||||
}
|
29
contracts/libraries/Address.sol
Normal file
29
contracts/libraries/Address.sol
Normal file
@ -0,0 +1,29 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @dev Collection of functions related to the address type,
|
||||
*/
|
||||
library Address {
|
||||
/**
|
||||
* @dev Returns true if `account` is a contract.
|
||||
*
|
||||
* This test is non-exhaustive, and there may be false-negatives: during the
|
||||
* execution of a contract's constructor, its address will be reported as
|
||||
* not containing a contract.
|
||||
*
|
||||
* > It is unsafe to assume that an address for which this function returns
|
||||
* false is an externally-owned account (EOA) and not a contract.
|
||||
*/
|
||||
function isContract(address account) internal view returns (bool) {
|
||||
// This method relies in extcodesize, which returns 0 for contracts in
|
||||
// construction, since the code is only stored at the end of the
|
||||
// constructor execution.
|
||||
|
||||
uint256 size;
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
size := extcodesize(account)
|
||||
}
|
||||
return size > 0;
|
||||
}
|
||||
}
|
77
contracts/libraries/SafeERC20.sol
Normal file
77
contracts/libraries/SafeERC20.sol
Normal file
@ -0,0 +1,77 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../interfaces/IERC20.sol";
|
||||
import "./SafeMath.sol";
|
||||
import "./Address.sol";
|
||||
|
||||
/**
|
||||
* @title SafeERC20
|
||||
* @dev Wrappers around ERC20 operations that throw on failure (when the token
|
||||
* contract returns false). Tokens that return no value (and instead revert or
|
||||
* throw on failure) are also supported, non-reverting calls are assumed to be
|
||||
* successful.
|
||||
* To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
|
||||
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
|
||||
*/
|
||||
library SafeERC20 {
|
||||
using SafeMath for uint256;
|
||||
using Address for address;
|
||||
|
||||
function safeTransfer(IERC20 token, address to, uint256 value) internal {
|
||||
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
|
||||
}
|
||||
|
||||
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
|
||||
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
|
||||
}
|
||||
|
||||
function safeApprove(IERC20 token, address spender, uint256 value) internal {
|
||||
// safeApprove should only be called when setting an initial allowance,
|
||||
// or when resetting it to zero. To increase and decrease it, use
|
||||
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(
|
||||
(value == 0) || (token.allowance(address(this), spender) == 0),
|
||||
"SafeERC20: approve from non-zero to non-zero allowance"
|
||||
);
|
||||
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
|
||||
}
|
||||
|
||||
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
|
||||
uint256 newAllowance = token.allowance(address(this), spender).add(value);
|
||||
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
|
||||
}
|
||||
|
||||
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
|
||||
uint256 newAllowance = token.allowance(address(this), spender).sub(value);
|
||||
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
|
||||
* on the return value: the return value is optional (but if data is returned, it must not be false).
|
||||
* @param token The token targeted by the call.
|
||||
* @param data The call data (encoded using abi.encode or one of its variants).
|
||||
*/
|
||||
function callOptionalReturn(IERC20 token, bytes memory data) private {
|
||||
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
|
||||
// we're implementing it ourselves.
|
||||
|
||||
// A Solidity high level call has three parts:
|
||||
// 1. The target address is checked to verify it contains contract code
|
||||
// 2. The call itself is made, and success asserted
|
||||
// 3. The return value is decoded, which in turn checks the size of the returned data.
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(address(token).isContract(), "SafeERC20: call to non-contract");
|
||||
|
||||
// solhint-disable-next-line avoid-low-level-calls
|
||||
(bool success, bytes memory returndata) = address(token).call(data);
|
||||
require(success, "SafeERC20: low-level call failed");
|
||||
|
||||
if (returndata.length > 0) {
|
||||
// Return data is optional
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
|
||||
}
|
||||
}
|
||||
}
|
107
contracts/libraries/SafeMath.sol
Normal file
107
contracts/libraries/SafeMath.sol
Normal file
@ -0,0 +1,107 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @dev Wrappers over Solidity's arithmetic operations with added overflow
|
||||
* checks.
|
||||
*
|
||||
* Arithmetic operations in Solidity wrap on overflow. This can easily result
|
||||
* in bugs, because programmers usually assume that an overflow raises an
|
||||
* error, which is the standard behavior in high level programming languages.
|
||||
* `SafeMath` restores this intuition by reverting the transaction when an
|
||||
* operation overflows.
|
||||
*
|
||||
* Using this library instead of the unchecked operations eliminates an entire
|
||||
* class of bugs, so it's recommended to use it always.
|
||||
*/
|
||||
library SafeMath {
|
||||
/**
|
||||
* @dev Returns the addition of two unsigned integers, reverting on
|
||||
* overflow.
|
||||
*
|
||||
* Counterpart to Solidity's `+` operator.
|
||||
*
|
||||
* Requirements:
|
||||
* - Addition cannot overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a, "SafeMath: addition overflow");
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the subtraction of two unsigned integers, reverting on
|
||||
* overflow (when the result is negative).
|
||||
*
|
||||
* Counterpart to Solidity's `-` operator.
|
||||
*
|
||||
* Requirements:
|
||||
* - Subtraction cannot overflow.
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b <= a, "SafeMath: subtraction overflow");
|
||||
uint256 c = a - b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the multiplication of two unsigned integers, reverting on
|
||||
* overflow.
|
||||
*
|
||||
* Counterpart to Solidity's `*` operator.
|
||||
*
|
||||
* Requirements:
|
||||
* - Multiplication cannot overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 c = a * b;
|
||||
require(c / a == b, "SafeMath: multiplication overflow");
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the integer division of two unsigned integers. Reverts on
|
||||
* division by zero. The result is rounded towards zero.
|
||||
*
|
||||
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
||||
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
||||
* uses an invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Solidity only automatically asserts when dividing by 0
|
||||
require(b > 0, "SafeMath: division by zero");
|
||||
uint256 c = a / b;
|
||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
||||
* Reverts when dividing by zero.
|
||||
*
|
||||
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
||||
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
||||
* invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b != 0, "SafeMath: modulo by zero");
|
||||
return a % b;
|
||||
}
|
||||
}
|
25
contracts/libraries/Types.sol
Normal file
25
contracts/libraries/Types.sol
Normal file
@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity >=0.5.17;
|
||||
|
||||
/**
|
||||
* @title Sablier Types
|
||||
* @author Sablier
|
||||
*/
|
||||
library Types {
|
||||
struct Stream {
|
||||
uint256 deposit;
|
||||
uint256 ratePerSecond;
|
||||
uint256 remainingBalance;
|
||||
uint256 initialLockedBalance;
|
||||
uint256 startTime;
|
||||
uint256 stopTime;
|
||||
address recipient;
|
||||
bool isEntity;
|
||||
}
|
||||
|
||||
struct Recipient {
|
||||
address addr;
|
||||
uint256 deposit;
|
||||
uint256 initialLockedBalance;
|
||||
}
|
||||
}
|
774
data/stakers.json
Normal file
774
data/stakers.json
Normal file
@ -0,0 +1,774 @@
|
||||
[
|
||||
{
|
||||
"address": "0xA29DbaA84a9949A0A38a2Ba07E0b75e6603934DB",
|
||||
"balance": "222061659733700101062"
|
||||
},
|
||||
{
|
||||
"address": "0xe9B4aA5906C6e842e52aE7B7ab4dec3EE52362cB",
|
||||
"balance": "187871680391712414210"
|
||||
},
|
||||
{
|
||||
"address": "0x642df98E9d71Ba533dF7288512cF63D34a907659",
|
||||
"balance": "3274920890240498949168"
|
||||
},
|
||||
{
|
||||
"address": "0x97b90FBc8904F861F76CB06BFa0A465b72C5E662",
|
||||
"balance": "1957577871492703175932"
|
||||
},
|
||||
{
|
||||
"address": "0xBFb910652F850F85E3F85AA0C12aE8f4037095b0",
|
||||
"balance": "18064223509187007832993"
|
||||
},
|
||||
{
|
||||
"address": "0xe2506955723C01dDd6e619dD0829e28F76328c41",
|
||||
"balance": "369300000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x3Df488Bd07C2082E84B1CD63F343Cf3d538342bA",
|
||||
"balance": "268606679563771005193"
|
||||
},
|
||||
{
|
||||
"address": "0x92F82EF0D08d8ADa7f542fC300adfd0b712b5963",
|
||||
"balance": "3614275869036584865053"
|
||||
},
|
||||
{
|
||||
"address": "0x65C6AA5521F9b149E918A9A44A44FD651dF0AFF3",
|
||||
"balance": "1337537896786103209588"
|
||||
},
|
||||
{
|
||||
"address": "0x25713B024a8004727Ba79c43647a77c7447948dB",
|
||||
"balance": "327316949018727268744"
|
||||
},
|
||||
{
|
||||
"address": "0xB157ba30e3467DdBC844f14F02b4ba741f1d549F",
|
||||
"balance": "300000008217141924923"
|
||||
},
|
||||
{
|
||||
"address": "0x83c418D2eD6670785330B996b47a18492b61e218",
|
||||
"balance": "24604927081108500781847"
|
||||
},
|
||||
{
|
||||
"address": "0x39978cc40e2D1d7E127050bDFFFBB0dFcfaEbAd0",
|
||||
"balance": "407032960152083087629"
|
||||
},
|
||||
{
|
||||
"address": "0x1d7979F557BA38892f25D3d54Fa6C1D75a4CfA27",
|
||||
"balance": "176136388919542490495"
|
||||
},
|
||||
{
|
||||
"address": "0x9433ea2C250D84d3fD6398699D48728fa610569A",
|
||||
"balance": "320126637964798831618"
|
||||
},
|
||||
{
|
||||
"address": "0xF99d1946Bf038a1205d430Ec91401E760e5F8F6F",
|
||||
"balance": "37075508978146311050113"
|
||||
},
|
||||
{
|
||||
"address": "0x9897Bc7231492CDf163BB81bFF10A5919a73d132",
|
||||
"balance": "9523810000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x9C42EBDf0fA6fA0274aEEBf981613Dfa9c99BFF8",
|
||||
"balance": "43892178461318681920771"
|
||||
},
|
||||
{
|
||||
"address": "0xeE1D1ac27A80De54F0ba92b2E25EBb3418495db2",
|
||||
"balance": "2331546926022547020105"
|
||||
},
|
||||
{
|
||||
"address": "0xefe8Aa053Ef0C9F1879911ef1C83Da08AD385164",
|
||||
"balance": "306015687989988508846"
|
||||
},
|
||||
{
|
||||
"address": "0x238926025E84475e3182774df480021470f8F978",
|
||||
"balance": "119748510011508001412"
|
||||
},
|
||||
{
|
||||
"address": "0x0c3a4a0ed70fDB29860760b5ca78B116Fe77DE00",
|
||||
"balance": "140306615000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x54F2f104Fb6ABf1a6991150B27662Aade958A338",
|
||||
"balance": "319349649026838373837"
|
||||
},
|
||||
{
|
||||
"address": "0x327346e623A4334f7c4034D5a73Ac636d33a31c0",
|
||||
"balance": "304751021776330822150"
|
||||
},
|
||||
{
|
||||
"address": "0xeafa6FbaebB26F9d07B42f3Fd8906818CE75026F",
|
||||
"balance": "922236496491056455335"
|
||||
},
|
||||
{
|
||||
"address": "0xe443cbad516eE9b00A2CbE7F884A4bb314776dE3",
|
||||
"balance": "64680368781627387285673"
|
||||
},
|
||||
{
|
||||
"address": "0x2D56db2f95Ae61c2396d30ABEa61fc91E506943F",
|
||||
"balance": "135065031612858769227"
|
||||
},
|
||||
{
|
||||
"address": "0xc7557AfDB4C2EF7E2A5e68ed60B1f8AC41c87459",
|
||||
"balance": "100170264404649634361"
|
||||
},
|
||||
{
|
||||
"address": "0x6eA8BfAa4697187D3BB1E27688931d73BcbbEC0b",
|
||||
"balance": "439287784325687715732"
|
||||
},
|
||||
{
|
||||
"address": "0xE0a9Cf94C4c41a7709B55D9bA37D788A8DF19F9E",
|
||||
"balance": "118418383918603784875"
|
||||
},
|
||||
{
|
||||
"address": "0x06F166E11d765aE936E7ec36777E1b4B6f0Cb83B",
|
||||
"balance": "180305703889462319555"
|
||||
},
|
||||
{
|
||||
"address": "0x1023aE712D5F219e9166a9D286e183226DFAafa6",
|
||||
"balance": "143712248142294445923"
|
||||
},
|
||||
{
|
||||
"address": "0x75F3fC9189fd3228a4178e544CdE26b75Da81Bf3",
|
||||
"balance": "547090923569720095523"
|
||||
},
|
||||
{
|
||||
"address": "0x90e14E059B28Af64B52d4Da0442b22052f507eF1",
|
||||
"balance": "906706256793263291165"
|
||||
},
|
||||
{
|
||||
"address": "0x344651A2445484bd2928eB46D2610DaaC1B42A66",
|
||||
"balance": "244547007283286030643"
|
||||
},
|
||||
{
|
||||
"address": "0x2490419318b3F69e8dc209604056f40Eb350d0d7",
|
||||
"balance": "1641166788776420175594"
|
||||
},
|
||||
{
|
||||
"address": "0x4aAE2d5072385b02465263d5feb91bb1995D4f37",
|
||||
"balance": "133266200000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x0df59978Cc975e27C5E4e19d355e025F0770F088",
|
||||
"balance": "1278073898007810414591"
|
||||
},
|
||||
{
|
||||
"address": "0x85e6C3c83929eE45712EFF4F89c5E74cCddB5D41",
|
||||
"balance": "220168850000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xC346A5dc3b3821AEeF3f3fFB70989631521E41cD",
|
||||
"balance": "224707550488945833056"
|
||||
},
|
||||
{
|
||||
"address": "0x5d17B355538A9ea9b45A0018e11b36947fC16376",
|
||||
"balance": "3461949885239649131822"
|
||||
},
|
||||
{
|
||||
"address": "0xAaF7168Bae99a4860D7729745B22C4b48d1f9Adb",
|
||||
"balance": "100475944611586099877"
|
||||
},
|
||||
{
|
||||
"address": "0xB835b4e277094D4AF9Fbb66e9f5Db9e6E8dC65dB",
|
||||
"balance": "2499187111378392690208"
|
||||
},
|
||||
{
|
||||
"address": "0x42DbF634c256acd17beDDC1330488F1BEa7B8BDf",
|
||||
"balance": "6877216358537763535178"
|
||||
},
|
||||
{
|
||||
"address": "0xE7304bA0f157f2Ade94015934284b6704BC72911",
|
||||
"balance": "112608649098976008132"
|
||||
},
|
||||
{
|
||||
"address": "0x3eE9378Fb0809a243FcF7C30865941675d766D71",
|
||||
"balance": "2774004155905058916423"
|
||||
},
|
||||
{
|
||||
"address": "0x81348BB6CFA32662cE76aE5FcC8c54F056CE7042",
|
||||
"balance": "100400761930000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x06981EfbE070996654482F4F20786e0CEf0f8740",
|
||||
"balance": "32754177841356351554810"
|
||||
},
|
||||
{
|
||||
"address": "0x92e74E50edCE4573d181C03cA889f72640cD3a94",
|
||||
"balance": "407199993263279657437"
|
||||
},
|
||||
{
|
||||
"address": "0x3dD44f129563787449367046c9cBF5610f21467f",
|
||||
"balance": "196204479061497808556"
|
||||
},
|
||||
{
|
||||
"address": "0x0A54cf15a8719DB69B5cC40d797a213ca9407B8E",
|
||||
"balance": "370960788258305263912"
|
||||
},
|
||||
{
|
||||
"address": "0x95880f2E70203f759168665Feb6948E81Fe5dF77",
|
||||
"balance": "294020437588528361099"
|
||||
},
|
||||
{
|
||||
"address": "0x0050faCd2C04930257438b213FE9E132a26E5a29",
|
||||
"balance": "119786423000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x1d14080067dE02E048DdE58a936b4EBED7ee56e4",
|
||||
"balance": "135408011012662929013"
|
||||
},
|
||||
{
|
||||
"address": "0xbb6d1648A8BeF51603Badd347Dc91eb7D04a43e5",
|
||||
"balance": "961751770023408248012"
|
||||
},
|
||||
{
|
||||
"address": "0xD7b2879C8922cd704E41E8CC1f18f6994D6B7C36",
|
||||
"balance": "1119299000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x7a628E9bCC082844797C37c79084ed6BC99e6Abc",
|
||||
"balance": "138985632834248119775"
|
||||
},
|
||||
{
|
||||
"address": "0xDaa5C5a5B6725666B1e37B14dc8e1FCB446c5952",
|
||||
"balance": "119080000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x5dab475E601D55efa2290D27333913e025C7Bd89",
|
||||
"balance": "146964212351551947890"
|
||||
},
|
||||
{
|
||||
"address": "0x4051e1fcD4Be1366a0CDcfA47ca717868A96575E",
|
||||
"balance": "561299291075539499694"
|
||||
},
|
||||
{
|
||||
"address": "0xB3AAd889bf41Ec39571aFa78aa5D9A26a05DDaAb",
|
||||
"balance": "208128000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x4303Ddc9943D862f2B205aF468a4A786c5137E76",
|
||||
"balance": "121978258758390804343"
|
||||
},
|
||||
{
|
||||
"address": "0xa1eBC8bdE2F1F87fe24F384497b6bD9cE3B14345",
|
||||
"balance": "2984693312345136089833"
|
||||
},
|
||||
{
|
||||
"address": "0xaf095d9cedBc20c8Bb0A75ED9509c1f31DC4E7E6",
|
||||
"balance": "4411294324551597847209"
|
||||
},
|
||||
{
|
||||
"address": "0x4839460F05b2a8fC1b615e0523EbC46eFba75420",
|
||||
"balance": "147677697371346056769"
|
||||
},
|
||||
{
|
||||
"address": "0x6b69c30354Cef94ee9d77DBC7BD268B4A6683825",
|
||||
"balance": "215671961915475600719"
|
||||
},
|
||||
{
|
||||
"address": "0x1CE7DC66CC98c61A573105514d073D64a9a8608f",
|
||||
"balance": "183302847714096393245"
|
||||
},
|
||||
{
|
||||
"address": "0x0d4E989c7620C8749c9417d2BF218896C767B606",
|
||||
"balance": "11111000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x4963C9C61f48272969587c27aA4e6384798d48cA",
|
||||
"balance": "646591448141274005553"
|
||||
},
|
||||
{
|
||||
"address": "0x6fb4becf05497b79F0fCF61CfA5075efAA137DDF",
|
||||
"balance": "118347626348277285232"
|
||||
},
|
||||
{
|
||||
"address": "0x6f9BB7e454f5B3eb2310343f0E99269dC2BB8A1d",
|
||||
"balance": "554530214763375646077"
|
||||
},
|
||||
{
|
||||
"address": "0xb4e39F6D3d386E98AF0C064E087aCBC9A8F08944",
|
||||
"balance": "147140882538472853905"
|
||||
},
|
||||
{
|
||||
"address": "0x2462375371935c8122895e701380A06CE815B0FD",
|
||||
"balance": "214282527968312078762"
|
||||
},
|
||||
{
|
||||
"address": "0x24f04EC62597C11752c47448228B63052ED3158a",
|
||||
"balance": "321761894521216575819"
|
||||
},
|
||||
{
|
||||
"address": "0x8904FFC6Aa039dB5941De11309a42372F3F7D2FD",
|
||||
"balance": "296350209248534143997"
|
||||
},
|
||||
{
|
||||
"address": "0xa729adDeFe1fa7BCe87053ed55D55EDdDD13De60",
|
||||
"balance": "105257962571588444433"
|
||||
},
|
||||
{
|
||||
"address": "0x9265f86d58b348060E43216f968bda8A6Bb63572",
|
||||
"balance": "462054994392400414840"
|
||||
},
|
||||
{
|
||||
"address": "0xcE1fFD4cfE424757D6e597293566195Fba6f4cD8",
|
||||
"balance": "378325759765781498396"
|
||||
},
|
||||
{
|
||||
"address": "0x2E63Dbd91657dc5fa97213Ba6a1AEb5f194805F6",
|
||||
"balance": "1200089842937217922038"
|
||||
},
|
||||
{
|
||||
"address": "0x4273397532A8dF43a6607C4441e3EB6edF63acf3",
|
||||
"balance": "150000000000000000037"
|
||||
},
|
||||
{
|
||||
"address": "0xC68c10C524eC53A284FB76a91b2e97F15Fe79634",
|
||||
"balance": "1295708210000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x12168AEa666Be756E1aD0595fEd9C306442a4103",
|
||||
"balance": "129858882018647549604"
|
||||
},
|
||||
{
|
||||
"address": "0xE70eF2B9A263855535727Ee014C6Ffaf01881Ae3",
|
||||
"balance": "126263397985613051754"
|
||||
},
|
||||
{
|
||||
"address": "0x5Fc0A53A7e33Aa6E41A93b718DD2216707251fC2",
|
||||
"balance": "1216512730000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x18F516dD6D5F46b2875Fd822B994081274be2a8b",
|
||||
"balance": "808879218854315691416"
|
||||
},
|
||||
{
|
||||
"address": "0x7803Ab56769dDa5432CDbd63749a6BEeb3180008",
|
||||
"balance": "1000020482341666374383"
|
||||
},
|
||||
{
|
||||
"address": "0x4F50d47D20380172746527bbeAa274940C38EFAC",
|
||||
"balance": "489392817721401322749"
|
||||
},
|
||||
{
|
||||
"address": "0xFeAe121618049802Ccb40f094536a7B186642699",
|
||||
"balance": "748171152585153967146"
|
||||
},
|
||||
{
|
||||
"address": "0x069Dd24FC8ABEC3708841a4726617c17BC74d5eC",
|
||||
"balance": "4465692444586264801956"
|
||||
},
|
||||
{
|
||||
"address": "0x11A2A99396c1BC4D878c9ac86401d38d5f2f4caE",
|
||||
"balance": "1841131594759449968212"
|
||||
},
|
||||
{
|
||||
"address": "0x26D3b88d464A575784Be70Edc5F9290dC5e296DB",
|
||||
"balance": "4584368997732369384071"
|
||||
},
|
||||
{
|
||||
"address": "0x7Abbdbd51813d85B448F887b946719Dd2B09D6F7",
|
||||
"balance": "477257927573167840914"
|
||||
},
|
||||
{
|
||||
"address": "0xEb89EfE3Ed80288E310c5529e1E242b4ab56E196",
|
||||
"balance": "1300090776209185468018"
|
||||
},
|
||||
{
|
||||
"address": "0xAD142B79f2500Bf194C174f06C7dC901A2CdA74f",
|
||||
"balance": "174034164798218427885"
|
||||
},
|
||||
{
|
||||
"address": "0x4fFDAeB9f4ec23254B6DFA41eEeF2C8d23f8c554",
|
||||
"balance": "131502368878796458509"
|
||||
},
|
||||
{
|
||||
"address": "0xb03384cA294C06E8d04B08412E8467ff2363E5E3",
|
||||
"balance": "906139663513082751610"
|
||||
},
|
||||
{
|
||||
"address": "0x6A3738c6299f45c31697aceA647D49EdCC9C28A4",
|
||||
"balance": "426032828677716268597"
|
||||
},
|
||||
{
|
||||
"address": "0xc74d1af789F5A0223448Db69a1B56c84845e17d5",
|
||||
"balance": "386136667062531373859"
|
||||
},
|
||||
{
|
||||
"address": "0xDf90418385aF4E9833603069DEaF7C71d76f83a2",
|
||||
"balance": "683465828138249494426"
|
||||
},
|
||||
{
|
||||
"address": "0x16eb5Fbb2a5c7dAbC2c7688482378e89471d5724",
|
||||
"balance": "251802411781229744678"
|
||||
},
|
||||
{
|
||||
"address": "0x356eE97D7D560af2E97E9f9EEe56b2e09D60e6F5",
|
||||
"balance": "10836062927446519092234"
|
||||
},
|
||||
{
|
||||
"address": "0x21c756E2c7B898BDa8a3b2A77e4C56D855Ab9414",
|
||||
"balance": "261098218101404112455"
|
||||
},
|
||||
{
|
||||
"address": "0xFB96D60ce3ee83ed4BC71c6E0da10C537601b77C",
|
||||
"balance": "446702746160587197664"
|
||||
},
|
||||
{
|
||||
"address": "0xeb0fCD59212E521918b514c64313eF5a3dd101f8",
|
||||
"balance": "100240415124564555330"
|
||||
},
|
||||
{
|
||||
"address": "0x34DF0B83cf4F30683f8AB2Ac971a52A5f663FEb4",
|
||||
"balance": "116124431887044456353"
|
||||
},
|
||||
{
|
||||
"address": "0xF2Ba32f180B243D3138DEd0E1F1BdbdcCBCE0702",
|
||||
"balance": "1482848214495146566693"
|
||||
},
|
||||
{
|
||||
"address": "0xbC063735a5b8bdd12611157E7E0F29D1570D892D",
|
||||
"balance": "509451890000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xe7c724F87EcFf8E2f563962f96b6c291cBD729cF",
|
||||
"balance": "250243001109044335565"
|
||||
},
|
||||
{
|
||||
"address": "0x1fe7d323946A7C3B644528baA42eFf13056cd2B4",
|
||||
"balance": "2012288953464165015019"
|
||||
},
|
||||
{
|
||||
"address": "0x48c0477Bf79a59e505d26eB33c5b331502a511B2",
|
||||
"balance": "11028610297596262814514"
|
||||
},
|
||||
{
|
||||
"address": "0xE5A5BfC1772D4A2b44Add05aae63026A89486C1B",
|
||||
"balance": "2897272017864013753943"
|
||||
},
|
||||
{
|
||||
"address": "0x00377B2FC0044Dec6507855eDd6531aF1755cCe4",
|
||||
"balance": "942500316330675833924"
|
||||
},
|
||||
{
|
||||
"address": "0xD9D10dc5609d77F2A15FAa68414835A6ed19269B",
|
||||
"balance": "604677796610747756803"
|
||||
},
|
||||
{
|
||||
"address": "0xdF20a1124d6B44e19ad75675a622d9c9669E59B6",
|
||||
"balance": "720900000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xF4d2D64D1f9190A9daB0960c80e5C73c04710184",
|
||||
"balance": "630536604758334996358"
|
||||
},
|
||||
{
|
||||
"address": "0xf68de31d7fC80A70959966F9Aa78e86A7b418A10",
|
||||
"balance": "100424753924039137153"
|
||||
},
|
||||
{
|
||||
"address": "0x47B9cCa44fe405D12ff56aaCd1Df6dbA4A79Ae28",
|
||||
"balance": "1198321376929923406445"
|
||||
},
|
||||
{
|
||||
"address": "0x71917F124be5C0Cd97aDBE7AB472f4C82577B542",
|
||||
"balance": "171985544540000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x2a2a1FB6382a528F1B23E76d3Ed6F4C17A9e5966",
|
||||
"balance": "679861011890874134021"
|
||||
},
|
||||
{
|
||||
"address": "0x343F48B346b0cE11342ffdEDaDAC4135E1FD525a",
|
||||
"balance": "1112013784183226328856"
|
||||
},
|
||||
{
|
||||
"address": "0x958622B4631212DC751c5B1Ba45013c833Dcb86c",
|
||||
"balance": "1000000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x0F46576F3b8b0ed6522e4b200Df53ac73251b911",
|
||||
"balance": "440579268126896398907"
|
||||
},
|
||||
{
|
||||
"address": "0xaAaC34d30d6938787c653AAfB922bc20bFa9C512",
|
||||
"balance": "2313674300000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x758aB8aC42a8c44dF8C31129Db146c65c2669391",
|
||||
"balance": "9999580000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x149da2CB603A8818Fb2d703D72D46390Cd09A6D9",
|
||||
"balance": "351315917791207543375"
|
||||
},
|
||||
{
|
||||
"address": "0xC2e6B265cb965DED721566f0f9Eb5ab1A6162A21",
|
||||
"balance": "2004486788385385993147"
|
||||
},
|
||||
{
|
||||
"address": "0x4e3072f7b5C075EA5FdEb423DA95312C4B99dc22",
|
||||
"balance": "3776301446297895060890"
|
||||
},
|
||||
{
|
||||
"address": "0x4d6A11EbEC10E133A5007578Ad792F765ED724F2",
|
||||
"balance": "19993341693923915158883"
|
||||
},
|
||||
{
|
||||
"address": "0x4F0535b9F0ad2f08dd01Fb4DA3ED15718978B2a9",
|
||||
"balance": "1713558815628887133179"
|
||||
},
|
||||
{
|
||||
"address": "0xddbc1841BE23b2ab55501Deb4d6bc39E3f8AA2d7",
|
||||
"balance": "48363478557462694029018"
|
||||
},
|
||||
{
|
||||
"address": "0x7b5edF38D955dd9deC103aF05c2D68B28e02Ad90",
|
||||
"balance": "29597872806644626228418"
|
||||
},
|
||||
{
|
||||
"address": "0xE4143f6377AEcd7193b9731d1C28815b57C4f5Ab",
|
||||
"balance": "98406849008651890866330"
|
||||
},
|
||||
{
|
||||
"address": "0x9Fd4d0dE8A3A8a8F2aC003A5ece295CE9512d9c6",
|
||||
"balance": "16038729098845967400725"
|
||||
},
|
||||
{
|
||||
"address": "0xa39fE8D3094e2D69Bd579Dc2bc2fc44Feb54Fc57",
|
||||
"balance": "62364443294474230012244"
|
||||
},
|
||||
{
|
||||
"address": "0x6f4CbC2E042ed0D1Df4bf14d00eEb52Ff1E0e5F8",
|
||||
"balance": "632357477375385036674"
|
||||
},
|
||||
{
|
||||
"address": "0x92374BA66EE27f207F9efff0837FF6D707006304",
|
||||
"balance": "26511566449802577442283"
|
||||
},
|
||||
{
|
||||
"address": "0x9Ff3C1Bea9ffB56a78824FE29f457F066257DD58",
|
||||
"balance": "1081206035039738702927"
|
||||
},
|
||||
{
|
||||
"address": "0x94596B6A626392F5D972D6CC4D929a42c2f0008c",
|
||||
"balance": "6237585974021878690758"
|
||||
},
|
||||
{
|
||||
"address": "0x065f2A0eF62878e8951af3c387E4ddC944f1B8F4",
|
||||
"balance": "289834051536966486101"
|
||||
},
|
||||
{
|
||||
"address": "0x7C199A0f301913212cfAB3756c3ed8F5B8927713",
|
||||
"balance": "7414560240165695407853"
|
||||
},
|
||||
{
|
||||
"address": "0x544F1D81aF6DdA4ca3Be8E1B8f28a3C270a007bb",
|
||||
"balance": "1423536639305809866205"
|
||||
},
|
||||
{
|
||||
"address": "0x8Fec4550BF2D184950391f3e053eD7A9557A5FE5",
|
||||
"balance": "7924889676611148883137"
|
||||
},
|
||||
{
|
||||
"address": "0x50042C58F7F55d62EC5275F67Ac4F847e4c93FBb",
|
||||
"balance": "13849331891297736274686"
|
||||
},
|
||||
{
|
||||
"address": "0x1c24ca7497947F8317Ccb2BfA9E404Fc57Aa3f0F",
|
||||
"balance": "39291332117152764542755"
|
||||
},
|
||||
{
|
||||
"address": "0x64Cd976be8b37db8402C65eae0893E94F21D3556",
|
||||
"balance": "3166824297101437639597"
|
||||
},
|
||||
{
|
||||
"address": "0x7268335b68638B16F4A86360f3E9eb322301ab90",
|
||||
"balance": "1053386541481860916683"
|
||||
},
|
||||
{
|
||||
"address": "0xBEF6d320Ed305BC9a0977D312c0c1BF9f56749D4",
|
||||
"balance": "16792018296955216982422"
|
||||
},
|
||||
{
|
||||
"address": "0x6e1Ea6FCEE2221844950FB269780BB450f47b6Ee",
|
||||
"balance": "55567601300164580084708"
|
||||
},
|
||||
{
|
||||
"address": "0x25a3BD3A11DDf704b695a185143Ad582936724EA",
|
||||
"balance": "52522786968174962240266"
|
||||
},
|
||||
{
|
||||
"address": "0xAd0dC9b5bf4308Cc26C1d44E1BEB2d30c43Bca1b",
|
||||
"balance": "146313191178089164638730"
|
||||
},
|
||||
{
|
||||
"address": "0xfA9330bb565c2F502D371a96A9F43D9182D732c9",
|
||||
"balance": "2932970328956661635966"
|
||||
},
|
||||
{
|
||||
"address": "0x09AdFab2635dcb681FADA41CeB0bfa6f52EFfd97",
|
||||
"balance": "73474731701589249491935"
|
||||
},
|
||||
{
|
||||
"address": "0xb5a07432eEe9a07176E6Da4B25b2b04a00C2407B",
|
||||
"balance": "17680387515310000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xeb3E49Af2aB5D5D0f83A9289cF5a34d9e1f6C5b4",
|
||||
"balance": "1011706736327691989355"
|
||||
},
|
||||
{
|
||||
"address": "0xD97938E0EAa80d8801174e6cF3E7155C872aDdcD",
|
||||
"balance": "11018292609207029948990"
|
||||
},
|
||||
{
|
||||
"address": "0xa5c4024fFb7C28516DAC1D83B3f92e5FeE7D3c22",
|
||||
"balance": "7177114122787556481405"
|
||||
},
|
||||
{
|
||||
"address": "0x9DD56f43baB75551114fce768b7F85aBcbc4d61c",
|
||||
"balance": "4862000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xef5031F705dfBD187B7F6A86f4173cB067afD1A9",
|
||||
"balance": "42729083148460923251275"
|
||||
},
|
||||
{
|
||||
"address": "0xFB7c1D49e006eaDdff2385c7eF8B0C5Cf49d038A",
|
||||
"balance": "1758194322344402845627"
|
||||
},
|
||||
{
|
||||
"address": "0x0AD50B53b0c142432c5f6c5c1fA1e4bb03021374",
|
||||
"balance": "10000000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xa99a29c335590685cCeaCeD2A0dBAf2C099CBeD9",
|
||||
"balance": "170002896000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xa983D03A49C15dE8AF54b313B0C9D4d1e489D600",
|
||||
"balance": "1249862822519364975935"
|
||||
},
|
||||
{
|
||||
"address": "0x9b78e16456c8C0A1FE386894c6f1E7F7C0104ADC",
|
||||
"balance": "1000000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xD98f8EB41e46C5D22e6eD7A2fE720af3D8DBFcd6",
|
||||
"balance": "74604454901819108700316"
|
||||
},
|
||||
{
|
||||
"address": "0xBf1F678061DFca5Dee9D85796751D3bb2dc64DE6",
|
||||
"balance": "2475233242348013353909"
|
||||
},
|
||||
{
|
||||
"address": "0xC0F12799B8D3FA8810DfE1616095170C72117F8F",
|
||||
"balance": "6096614520309199098544"
|
||||
},
|
||||
{
|
||||
"address": "0x8eD607D5E14EEc65DbcFe015905E7c19d3Dbe600",
|
||||
"balance": "39407794500000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xE5bbc8C362EB53C6f7264C94d969B5a7962A11DF",
|
||||
"balance": "11790930224760000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xBa9B359C89Bb8B8985b7BeDba7fF143abBD2dadD",
|
||||
"balance": "5287777839235049283919"
|
||||
},
|
||||
{
|
||||
"address": "0x13CC8E623098Bb7076a7ae179A2A309282428589",
|
||||
"balance": "89840000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x5aAF2c73342eEdb0B295f0DB7641FAB6e2e0ede7",
|
||||
"balance": "11177220714563111217644"
|
||||
},
|
||||
{
|
||||
"address": "0x88cafaD2072054b5a641150C8710062D11C296Ad",
|
||||
"balance": "4960490823893811264302"
|
||||
},
|
||||
{
|
||||
"address": "0x43F3D8909819B681aDB64c50EbcaEb77689A101B",
|
||||
"balance": "9063225233738240554677"
|
||||
},
|
||||
{
|
||||
"address": "0x2d1270896be64F2A3835CBb0528313511840AE02",
|
||||
"balance": "2663650000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x28d5fdd7cD29f9676cc82f30ee4ff47C4aF3c5aB",
|
||||
"balance": "9230000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x9d8f0f4192643209F38f5E0D02E2504Eab6F15Ac",
|
||||
"balance": "10596676565182876169022"
|
||||
},
|
||||
{
|
||||
"address": "0x9d7f41108Cd351AEE210082a41896Af822F81156",
|
||||
"balance": "2184748060000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xD498265eb913f95BDd0618C67Fc41F82aC1F8E0E",
|
||||
"balance": "2406194461606211909460"
|
||||
},
|
||||
{
|
||||
"address": "0x3376E7f9510b566f8CC6AB9e4F4588d941A64685",
|
||||
"balance": "3000000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x516b55a1938C5306f2291fBd01C02C16B7E9B837",
|
||||
"balance": "5007812741016906817987"
|
||||
},
|
||||
{
|
||||
"address": "0x7bd70c6462220072cEd0E7873a98CF21aAA952dA",
|
||||
"balance": "6297877657280000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x26532eC1bb6b115a8Ae697be63D47122De02fCa7",
|
||||
"balance": "22733003153052279993119"
|
||||
},
|
||||
{
|
||||
"address": "0x5D9A3E0Cb733d566FA887b4b74776A8cF9250640",
|
||||
"balance": "287024310000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x9D1B637E76c0192b11aac1c59666866a8044f83d",
|
||||
"balance": "446950120000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0xa0Ea24593C1571fCcea113Fe7eC1e8dc81191025",
|
||||
"balance": "3700000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x1cE7260e0c5776A2834892e4452bdB099D6f0713",
|
||||
"balance": "43659039111640240367762"
|
||||
},
|
||||
{
|
||||
"address": "0xefC17Ff5dB1FbbF77304aB3423faab05BAA21d8C",
|
||||
"balance": "732170000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x0c9fCE6d71774709Ea41CAD8c55e171D5477DC18",
|
||||
"balance": "10282263191686831069699"
|
||||
},
|
||||
{
|
||||
"address": "0x4Bb93141ceAFb41856695cC4fC2c07f3a45A5265",
|
||||
"balance": "755139560000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x6Da70176136DaE6eFA25A3399bdA5aEC78215723",
|
||||
"balance": "17075770306076350632861"
|
||||
},
|
||||
{
|
||||
"address": "0xE68E072002B084EB674d4263aE6e992204705fB7",
|
||||
"balance": "1614550204755241657412"
|
||||
},
|
||||
{
|
||||
"address": "0x1cC43840c765f71d4B419944eA8CebA75eb6DFB0",
|
||||
"balance": "2500000000000000000000"
|
||||
},
|
||||
{
|
||||
"address": "0x6db80dCeB07984e36D6CB97EDeBCC34013fDa1a1",
|
||||
"balance": "4994201825300195752523"
|
||||
}
|
||||
]
|
60
hardhat.config.js
Normal file
60
hardhat.config.js
Normal file
@ -0,0 +1,60 @@
|
||||
require("@nomicfoundation/hardhat-toolbox");
|
||||
require("hardhat-gas-reporter");
|
||||
require("dotenv").config();
|
||||
|
||||
/** @type import('hardhat/config').HardhatUserConfig */
|
||||
module.exports = {
|
||||
solidity: {
|
||||
compilers: [
|
||||
{
|
||||
version: "0.8.20",
|
||||
},
|
||||
{
|
||||
version: "0.6.12",
|
||||
},
|
||||
{
|
||||
version: "0.5.17",
|
||||
},
|
||||
],
|
||||
},
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
},
|
||||
},
|
||||
mocha: {
|
||||
timeout: 100000000,
|
||||
},
|
||||
networks: {
|
||||
mainnet: {
|
||||
url: "https://ethereum.publicnode.com",
|
||||
accounts: [process.env.REAL_PK],
|
||||
},
|
||||
testnet: {
|
||||
url: "https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161",
|
||||
accounts: [process.env.TEST_PK],
|
||||
},
|
||||
hardhat: {
|
||||
forking: {
|
||||
url: "https://rpc.mevblocker.io/fast",
|
||||
enabled: true,
|
||||
blockNumber: 19104883,
|
||||
accounts: [process.env.REAL_PK],
|
||||
},
|
||||
chainId: 1,
|
||||
accounts: [
|
||||
{
|
||||
privateKey: process.env.REAL_PK,
|
||||
balance: "10000000000000000000000000000000",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
etherscan: {
|
||||
apiKey: process.env.ETHERSCAN_KEY,
|
||||
},
|
||||
gasReporter: {
|
||||
enabled: false,
|
||||
},
|
||||
};
|
17717
package-lock.json
generated
Normal file
17717
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
45
package.json
Normal file
45
package.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "proposal-47",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "hardhat.config.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "npx hardhat test",
|
||||
"deploy": "npx hardhat run --network mainnet scripts/deploy.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.2",
|
||||
"@nomicfoundation/hardhat-ethers": "^3.0.4",
|
||||
"@nomicfoundation/hardhat-network-helpers": "^1.0.9",
|
||||
"@nomicfoundation/hardhat-toolbox": "^3.0.0",
|
||||
"@nomicfoundation/hardhat-verify": "^1.1.1",
|
||||
"@typechain/ethers-v6": "^0.4.3",
|
||||
"@typechain/hardhat": "^8.0.3",
|
||||
"@types/chai": "^4.3.9",
|
||||
"@types/mocha": "^10.0.2",
|
||||
"chai": "^4.3.10",
|
||||
"chai-things": "^0.2.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"ethers": "^6.8.0",
|
||||
"hardhat": "^2.18.1",
|
||||
"hardhat-gas-reporter": "^1.0.9",
|
||||
"prettier": "^3.0.3",
|
||||
"prettier-plugin-solidity": "^1.1.3",
|
||||
"solidity-coverage": "^0.8.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"typechain": "^8.3.2",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@openzeppelin/contracts": "^3.2.0-rc.0",
|
||||
"@openzeppelin/upgrades-core": "^1.30.1",
|
||||
"base58-solidity": "^1.0.2",
|
||||
"content-hash": "^2.5.2",
|
||||
"torn-token": "^1.0.8"
|
||||
}
|
||||
}
|
18
scripts/calculateAirdrop.js
Normal file
18
scripts/calculateAirdrop.js
Normal file
@ -0,0 +1,18 @@
|
||||
const stakers = require("../data/stakers.json");
|
||||
const fs = require("fs");
|
||||
const { ethers } = require("hardhat");
|
||||
|
||||
async function getTorn() {
|
||||
return await ethers.getContractAt(require("../test/abi/torn.abi.json"), "0x77777FeDdddFfC19Ff86DB637967013e6C6A116C");
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const governanceAddr = "0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce";
|
||||
const governanceContract = await ethers.getContractAt(require("../test/abi/governance.abi.json"), governanceAddr);
|
||||
const airdropAmount = 1000000n * 10n ** 18n;
|
||||
const stakeAmount = stakers.reduce((acc, staker) => acc + BigInt(staker.balance), 0n);
|
||||
const vaultBalance = await (await getTorn()).balanceOf(await governanceContract.userVault());
|
||||
console.log(stakeAmount, vaultBalance);
|
||||
}
|
||||
|
||||
main();
|
38
scripts/deploy.js
Normal file
38
scripts/deploy.js
Normal file
@ -0,0 +1,38 @@
|
||||
// We require the Hardhat Runtime Environment explicitly here. This is optional
|
||||
// but useful for running the script in a standalone fashion through `node <script>`.
|
||||
//
|
||||
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
|
||||
// will compile your contracts, add the Hardhat Runtime Environment's members to the
|
||||
// global scope, and execute the script.
|
||||
const hre = require("hardhat");
|
||||
const { ethers } = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
const airdropFactory = await ethers.getContractFactory("SablierAirdrop");
|
||||
const airdrop = await airdropFactory.deploy();
|
||||
const airdropAddr = await airdrop.getAddress();
|
||||
let tx = airdrop.deploymentTransaction();
|
||||
await tx.wait(16);
|
||||
console.log("Aidrop deployment confirmed with 16 blocks, waiting for verification on Etherscan");
|
||||
await hre.run("verify:verify", {
|
||||
address: governanceImplAddr,
|
||||
contract: "contracts/Airdrop.sol:SablierAirdrop",
|
||||
constructorArguments: [stakingAddr, gasCompensationAddr, userVaultAddr],
|
||||
});
|
||||
|
||||
const proposalFactory = await ethers.getContractFactory("Proposal");
|
||||
const proposal = await proposalFactory.deploy(airdropAddr);
|
||||
const deployedProposalAddr = await proposal.getAddress();
|
||||
|
||||
await hre.run("verify:verify", {
|
||||
address: "0xc4217881856cA15c320B32A87F9ab3Ed17a5A9d0",
|
||||
contract: "contracts/Proposal.sol:Proposal",
|
||||
});
|
||||
}
|
||||
|
||||
// We recommend this pattern to be able to use async/await everywhere
|
||||
// and properly handle errors.
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
31
scripts/findStakers.js
Normal file
31
scripts/findStakers.js
Normal file
@ -0,0 +1,31 @@
|
||||
const { ethers } = require("hardhat");
|
||||
const fs = require("fs");
|
||||
|
||||
BigInt.prototype.toJSON = function () {
|
||||
return this.toString();
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const governanceAddr = "0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce";
|
||||
const governanceDeploymentBlock = 11480636;
|
||||
const governanceContract = await ethers.getContractAt(require("../test/abi/governance.abi.json"), governanceAddr);
|
||||
const filter = governanceContract.filters.RewardUpdateSuccessful;
|
||||
const events = await governanceContract.queryFilter(filter, governanceDeploymentBlock);
|
||||
const stakerAddresses = [...new Set(events.map((event) => event.args[0]))];
|
||||
const batch = 100;
|
||||
let allStakers = [];
|
||||
for (let i = 0; i < stakerAddresses.length; i += batch) {
|
||||
const part = stakerAddresses.slice(i, i + batch).map((addr) => governanceContract.lockedBalance(addr));
|
||||
const balances = await Promise.all(part);
|
||||
const resultsPart = balances.map((balance, k) => ({
|
||||
address: stakerAddresses[k + i],
|
||||
balance,
|
||||
}));
|
||||
allStakers.push(...resultsPart);
|
||||
}
|
||||
|
||||
const result = allStakers.filter((staker) => staker.balance > 100n * 10n ** 18n);
|
||||
fs.writeFileSync("data/stakers.json", JSON.stringify(result, null, 4), { encoding: "utf-8" });
|
||||
}
|
||||
|
||||
main();
|
69
test/Proposal.js
Normal file
69
test/Proposal.js
Normal file
@ -0,0 +1,69 @@
|
||||
const { ethers, network } = require("hardhat");
|
||||
const contentHash = require("content-hash");
|
||||
const { expect, assert } = require("chai");
|
||||
const { time } = require("@nomicfoundation/hardhat-toolbox/network-helpers");
|
||||
const { deployAndExecuteProposal } = require("./utils");
|
||||
|
||||
const tornAddr = "0x77777FeDdddFfC19Ff86DB637967013e6C6A116C";
|
||||
const sablierAddr = "0xCD18eAa163733Da39c232722cBC4E8940b1D8888";
|
||||
const governanceAddr = "0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce";
|
||||
async function getManyEth(addr) {
|
||||
await network.provider.send("hardhat_setBalance", [addr, "0x111166630153555558483537"]);
|
||||
}
|
||||
|
||||
async function getEnsRegistry() {
|
||||
const ensAddr = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e";
|
||||
return await ethers.getContractAt(require("./abi/ensRegistry.abi.json"), ensAddr);
|
||||
}
|
||||
|
||||
async function getEnsResolver(ensName) {
|
||||
const ensRegistry = await getEnsRegistry();
|
||||
const resolverAddr = await ensRegistry.resolver(ethers.namehash(ensName));
|
||||
return await ethers.getContractAt(require("./abi/ensResolver.abi.json"), resolverAddr);
|
||||
}
|
||||
|
||||
async function resolveAddr(ensName) {
|
||||
if (ethers.isAddress(ensName)) return ensName;
|
||||
const ensResolver = await getEnsResolver(ensName);
|
||||
|
||||
return await ensResolver.addr(ethers.namehash(ensName));
|
||||
}
|
||||
|
||||
async function getTornContract() {
|
||||
return await ethers.getContractAt(require("./abi/torn.abi.json"), tornAddr);
|
||||
}
|
||||
|
||||
async function getSablierContract() {
|
||||
return await ethers.getContractAt(require("./abi/sabler.abi.json"), sablierAddr);
|
||||
}
|
||||
|
||||
async function getMe() {
|
||||
return await resolveAddr("butterfly-attractor.eth");
|
||||
}
|
||||
|
||||
describe("Proposal results check", function () {
|
||||
beforeEach(async function () {
|
||||
await network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
jsonRpcUrl: config.networks.hardhat.forking.url,
|
||||
blockNumber: config.networks.hardhat.forking.blockNumber,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
async function getStreamArgs() {
|
||||
const sablier = await getSablierContract();
|
||||
const filter = sablier.filters.CreateStream;
|
||||
const events = await sablier.queryFilter(filter, config.networks.hardhat.forking.blockNumber - 1);
|
||||
return events[0].args;
|
||||
}
|
||||
|
||||
it("Proposal executed", async function () {
|
||||
await deployAndExecuteProposal();
|
||||
});
|
||||
});
|
374
test/abi/airdrop.abi.json
Normal file
374
test/abi/airdrop.abi.json
Normal file
@ -0,0 +1,374 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "remainingBalance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "CancelStream",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "deposit",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "startTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "stopTime",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "CreateStream",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "WithdrawFromStream",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "who",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "cancelAirdrop",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "cancelStream",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "deposit",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"internalType": "struct Types.Recipient[]",
|
||||
"name": "recipients",
|
||||
"type": "tuple[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "startTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "stopTime",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "createAirdrop",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "deposit",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "startTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "stopTime",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "createStream",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "deltaOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "delta",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getStream",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "deposit",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "startTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "stopTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "remainingBalance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "ratePerSecond",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "nextStreamId",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "torn",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract IERC20",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "tornadoGovernance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "withdrawFromStream",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
274
test/abi/ensRegistry.abi.json
Normal file
274
test/abi/ensRegistry.abi.json
Normal file
@ -0,0 +1,274 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "contract ENS", "name": "_old", "type": "address" }
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bool",
|
||||
"name": "approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "ApprovalForAll",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "label",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "NewOwner",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "resolver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "NewResolver",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "ttl",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "NewTTL",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||
{ "internalType": "address", "name": "operator", "type": "address" }
|
||||
],
|
||||
"name": "isApprovedForAll",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "old",
|
||||
"outputs": [
|
||||
{ "internalType": "contract ENS", "name": "", "type": "address" }
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "owner",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "recordExists",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "resolver",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "operator", "type": "address" },
|
||||
{ "internalType": "bool", "name": "approved", "type": "bool" }
|
||||
],
|
||||
"name": "setApprovalForAll",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "owner", "type": "address" }
|
||||
],
|
||||
"name": "setOwner",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||
{ "internalType": "address", "name": "resolver", "type": "address" },
|
||||
{ "internalType": "uint64", "name": "ttl", "type": "uint64" }
|
||||
],
|
||||
"name": "setRecord",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "resolver", "type": "address" }
|
||||
],
|
||||
"name": "setResolver",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "label", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "owner", "type": "address" }
|
||||
],
|
||||
"name": "setSubnodeOwner",
|
||||
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "label", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||
{ "internalType": "address", "name": "resolver", "type": "address" },
|
||||
{ "internalType": "uint64", "name": "ttl", "type": "uint64" }
|
||||
],
|
||||
"name": "setSubnodeRecord",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "uint64", "name": "ttl", "type": "uint64" }
|
||||
],
|
||||
"name": "setTTL",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "ttl",
|
||||
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
671
test/abi/ensResolver.abi.json
Normal file
671
test/abi/ensResolver.abi.json
Normal file
@ -0,0 +1,671 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "contract ENS", "name": "_ens", "type": "address" },
|
||||
{
|
||||
"internalType": "contract INameWrapper",
|
||||
"name": "wrapperAddress",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_trustedETHController",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_trustedReverseRegistrar",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "contentType",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ABIChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "a",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddrChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "coinType",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes",
|
||||
"name": "newAddress",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "AddressChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bool",
|
||||
"name": "approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "ApprovalForAll",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "delegate",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bool",
|
||||
"name": "approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "Approved",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes",
|
||||
"name": "hash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "ContenthashChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes",
|
||||
"name": "name",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint16",
|
||||
"name": "resource",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes",
|
||||
"name": "record",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "DNSRecordChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes",
|
||||
"name": "name",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint16",
|
||||
"name": "resource",
|
||||
"type": "uint16"
|
||||
}
|
||||
],
|
||||
"name": "DNSRecordDeleted",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes",
|
||||
"name": "lastzonehash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes",
|
||||
"name": "zonehash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "DNSZonehashChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes4",
|
||||
"name": "interfaceID",
|
||||
"type": "bytes4"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "implementer",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "InterfaceChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "NameChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes32",
|
||||
"name": "x",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bytes32",
|
||||
"name": "y",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "PubkeyChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "string",
|
||||
"name": "indexedKey",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "key",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "value",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "TextChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "newVersion",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "VersionChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "uint256", "name": "contentTypes", "type": "uint256" }
|
||||
],
|
||||
"name": "ABI",
|
||||
"outputs": [
|
||||
{ "internalType": "uint256", "name": "", "type": "uint256" },
|
||||
{ "internalType": "bytes", "name": "", "type": "bytes" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "addr",
|
||||
"outputs": [
|
||||
{ "internalType": "address payable", "name": "", "type": "address" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "uint256", "name": "coinType", "type": "uint256" }
|
||||
],
|
||||
"name": "addr",
|
||||
"outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "delegate", "type": "address" },
|
||||
{ "internalType": "bool", "name": "approved", "type": "bool" }
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "clearRecords",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "contenthash",
|
||||
"outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "name", "type": "bytes32" },
|
||||
{ "internalType": "uint16", "name": "resource", "type": "uint16" }
|
||||
],
|
||||
"name": "dnsRecord",
|
||||
"outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "name", "type": "bytes32" }
|
||||
],
|
||||
"name": "hasDNSRecords",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }
|
||||
],
|
||||
"name": "interfaceImplementer",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "delegate", "type": "address" }
|
||||
],
|
||||
"name": "isApprovedFor",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "account", "type": "address" },
|
||||
{ "internalType": "address", "name": "operator", "type": "address" }
|
||||
],
|
||||
"name": "isApprovedForAll",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes[]", "name": "data", "type": "bytes[]" }
|
||||
],
|
||||
"name": "multicall",
|
||||
"outputs": [
|
||||
{ "internalType": "bytes[]", "name": "results", "type": "bytes[]" }
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "nodehash", "type": "bytes32" },
|
||||
{ "internalType": "bytes[]", "name": "data", "type": "bytes[]" }
|
||||
],
|
||||
"name": "multicallWithNodeCheck",
|
||||
"outputs": [
|
||||
{ "internalType": "bytes[]", "name": "results", "type": "bytes[]" }
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "name",
|
||||
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "pubkey",
|
||||
"outputs": [
|
||||
{ "internalType": "bytes32", "name": "x", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "y", "type": "bytes32" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
|
||||
"name": "recordVersions",
|
||||
"outputs": [{ "internalType": "uint64", "name": "", "type": "uint64" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "uint256", "name": "contentType", "type": "uint256" },
|
||||
{ "internalType": "bytes", "name": "data", "type": "bytes" }
|
||||
],
|
||||
"name": "setABI",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "uint256", "name": "coinType", "type": "uint256" },
|
||||
{ "internalType": "bytes", "name": "a", "type": "bytes" }
|
||||
],
|
||||
"name": "setAddr",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "address", "name": "a", "type": "address" }
|
||||
],
|
||||
"name": "setAddr",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "operator", "type": "address" },
|
||||
{ "internalType": "bool", "name": "approved", "type": "bool" }
|
||||
],
|
||||
"name": "setApprovalForAll",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes", "name": "hash", "type": "bytes" }
|
||||
],
|
||||
"name": "setContenthash",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes", "name": "data", "type": "bytes" }
|
||||
],
|
||||
"name": "setDNSRecords",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" },
|
||||
{ "internalType": "address", "name": "implementer", "type": "address" }
|
||||
],
|
||||
"name": "setInterface",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "string", "name": "newName", "type": "string" }
|
||||
],
|
||||
"name": "setName",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "x", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "y", "type": "bytes32" }
|
||||
],
|
||||
"name": "setPubkey",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "string", "name": "key", "type": "string" },
|
||||
{ "internalType": "string", "name": "value", "type": "string" }
|
||||
],
|
||||
"name": "setText",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "bytes", "name": "hash", "type": "bytes" }
|
||||
],
|
||||
"name": "setZonehash",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }
|
||||
],
|
||||
"name": "supportsInterface",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" },
|
||||
{ "internalType": "string", "name": "key", "type": "string" }
|
||||
],
|
||||
"name": "text",
|
||||
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "zonehash",
|
||||
"outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
636
test/abi/governance.abi.json
Normal file
636
test/abi/governance.abi.json
Normal file
@ -0,0 +1,636 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "stakingRewardsAddress",
|
||||
"type": "address"
|
||||
},
|
||||
{ "internalType": "address", "name": "gasCompLogic", "type": "address" },
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "userVaultAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Delegated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "id",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "proposer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "startTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "endTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "description",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "ProposalCreated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "proposalId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ProposalExecuted",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes",
|
||||
"name": "errorData",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "RewardUpdateFailed",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "RewardUpdateSuccessful",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Undelegated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "proposalId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "voter",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bool",
|
||||
"name": "support",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "votes",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Voted",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "CLOSING_PERIOD",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "EXECUTION_DELAY",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "EXECUTION_EXPIRATION",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "PROPOSAL_THRESHOLD",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "QUORUM_VOTES",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Staking",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract ITornadoStakingRewards",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "VOTE_EXTEND_TIME",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "VOTING_DELAY",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "VOTING_PERIOD",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32[]", "name": "domains", "type": "bytes32[]" }
|
||||
],
|
||||
"name": "bulkResolve",
|
||||
"outputs": [
|
||||
{ "internalType": "address[]", "name": "result", "type": "address[]" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"name": "canWithdrawAfter",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address[]", "name": "from", "type": "address[]" },
|
||||
{ "internalType": "uint256", "name": "proposalId", "type": "uint256" },
|
||||
{ "internalType": "bool", "name": "support", "type": "bool" }
|
||||
],
|
||||
"name": "castDelegatedVote",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "proposalId", "type": "uint256" },
|
||||
{ "internalType": "bool", "name": "support", "type": "bool" }
|
||||
],
|
||||
"name": "castVote",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "proposalId", "type": "uint256" }
|
||||
],
|
||||
"name": "checkIfQuorumReached",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "to", "type": "address" }],
|
||||
"name": "delegate",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"name": "delegatedTo",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "proposalId", "type": "uint256" }
|
||||
],
|
||||
"name": "execute",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "gasCompensationVault",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract IGasCompensationVault",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "proposalId", "type": "uint256" },
|
||||
{ "internalType": "address", "name": "voter", "type": "address" }
|
||||
],
|
||||
"name": "getReceipt",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{ "internalType": "bool", "name": "hasVoted", "type": "bool" },
|
||||
{ "internalType": "bool", "name": "support", "type": "bool" },
|
||||
{ "internalType": "uint256", "name": "votes", "type": "uint256" }
|
||||
],
|
||||
"internalType": "struct Governance.Receipt",
|
||||
"name": "",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "proposalId", "type": "uint256" },
|
||||
{ "internalType": "address", "name": "account", "type": "address" }
|
||||
],
|
||||
"name": "hasAccountVoted",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "_torn", "type": "bytes32" }
|
||||
],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"name": "latestProposalIds",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "deadline", "type": "uint256" },
|
||||
{ "internalType": "uint8", "name": "v", "type": "uint8" },
|
||||
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
|
||||
],
|
||||
"name": "lock",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "lockWithApproval",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"name": "lockedBalance",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"name": "proposalCodehashes",
|
||||
"outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proposalCount",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"name": "proposals",
|
||||
"outputs": [
|
||||
{ "internalType": "address", "name": "proposer", "type": "address" },
|
||||
{ "internalType": "address", "name": "target", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "startTime", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "endTime", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "forVotes", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "againstVotes", "type": "uint256" },
|
||||
{ "internalType": "bool", "name": "executed", "type": "bool" },
|
||||
{ "internalType": "bool", "name": "extended", "type": "bool" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "target", "type": "address" },
|
||||
{ "internalType": "string", "name": "description", "type": "string" }
|
||||
],
|
||||
"name": "propose",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "from", "type": "address" },
|
||||
{ "internalType": "address", "name": "target", "type": "address" },
|
||||
{ "internalType": "string", "name": "description", "type": "string" }
|
||||
],
|
||||
"name": "proposeByDelegate",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "resolve",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "returnMultisigAddress",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "closingPeriod", "type": "uint256" }
|
||||
],
|
||||
"name": "setClosingPeriod",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "executionDelay", "type": "uint256" }
|
||||
],
|
||||
"name": "setExecutionDelay",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "executionExpiration",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setExecutionExpiration",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "gasCompensationsLimit",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setGasCompensations",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "proposalThreshold",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setProposalThreshold",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "quorumVotes", "type": "uint256" }
|
||||
],
|
||||
"name": "setQuorumVotes",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "voteExtendTime", "type": "uint256" }
|
||||
],
|
||||
"name": "setVoteExtendTime",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "votingDelay", "type": "uint256" }
|
||||
],
|
||||
"name": "setVotingDelay",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "votingPeriod", "type": "uint256" }
|
||||
],
|
||||
"name": "setVotingPeriod",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "proposalId", "type": "uint256" }
|
||||
],
|
||||
"name": "state",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "enum Governance.ProposalState",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "torn",
|
||||
"outputs": [
|
||||
{ "internalType": "contract TORN", "name": "", "type": "address" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "undelegate",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "unlock",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "userVault",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract ITornadoVault",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "version",
|
||||
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "withdrawFromHelper",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{ "stateMutability": "payable", "type": "receive" }
|
||||
]
|
217
test/abi/sabler.abi.json
Normal file
217
test/abi/sabler.abi.json
Normal file
@ -0,0 +1,217 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "senderBalance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "recipientBalance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "CancelStream",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "deposit",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "tokenAddress",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "startTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "stopTime",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "CreateStream",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "streamId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "WithdrawFromStream",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "streamId", "type": "uint256" },
|
||||
{ "internalType": "address", "name": "who", "type": "address" }
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{ "internalType": "uint256", "name": "balance", "type": "uint256" }
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "streamId", "type": "uint256" }
|
||||
],
|
||||
"name": "cancelStream",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "recipient", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "deposit", "type": "uint256" },
|
||||
{ "internalType": "address", "name": "tokenAddress", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "startTime", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "stopTime", "type": "uint256" }
|
||||
],
|
||||
"name": "createStream",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "streamId", "type": "uint256" }
|
||||
],
|
||||
"name": "deltaOf",
|
||||
"outputs": [
|
||||
{ "internalType": "uint256", "name": "delta", "type": "uint256" }
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "streamId", "type": "uint256" }
|
||||
],
|
||||
"name": "getStream",
|
||||
"outputs": [
|
||||
{ "internalType": "address", "name": "sender", "type": "address" },
|
||||
{ "internalType": "address", "name": "recipient", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "deposit", "type": "uint256" },
|
||||
{ "internalType": "address", "name": "tokenAddress", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "startTime", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "stopTime", "type": "uint256" },
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "remainingBalance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{ "internalType": "uint256", "name": "ratePerSecond", "type": "uint256" }
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "nextStreamId",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "streamId", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "withdrawFromStream",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
370
test/abi/torn.abi.json
Normal file
370
test/abi/torn.abi.json
Normal file
@ -0,0 +1,370 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "_governance", "type": "bytes32" },
|
||||
{ "internalType": "uint256", "name": "_pausePeriod", "type": "uint256" },
|
||||
{
|
||||
"components": [
|
||||
{ "internalType": "bytes32", "name": "to", "type": "bytes32" },
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"internalType": "struct TORN.Recipient[]",
|
||||
"name": "_vestings",
|
||||
"type": "tuple[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Allowed",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Disallowed",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Paused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Unpaused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address[]", "name": "target", "type": "address[]" }
|
||||
],
|
||||
"name": "addToAllowedList",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||
{ "internalType": "address", "name": "spender", "type": "address" }
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"name": "allowedTransferee",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "spender", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "account", "type": "address" }
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "blockTimestamp",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32[]", "name": "domains", "type": "bytes32[]" }
|
||||
],
|
||||
"name": "bulkResolve",
|
||||
"outputs": [
|
||||
{ "internalType": "address[]", "name": "result", "type": "address[]" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "burn",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "account", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "burnFrom",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "canUnpauseAfter",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "chainID",
|
||||
"outputs": [
|
||||
{ "internalType": "uint256", "name": "_chainID", "type": "uint256" }
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [{ "internalType": "bool", "name": "decision", "type": "bool" }],
|
||||
"name": "changeTransferability",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "spender", "type": "address" },
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "subtractedValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "decreaseAllowance",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "governance",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "spender", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "addedValue", "type": "uint256" }
|
||||
],
|
||||
"name": "increaseAllowance",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "owner", "type": "address" }
|
||||
],
|
||||
"name": "nonces",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "paused",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||
{ "internalType": "address", "name": "spender", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" },
|
||||
{ "internalType": "uint256", "name": "deadline", "type": "uint256" },
|
||||
{ "internalType": "uint8", "name": "v", "type": "uint8" },
|
||||
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
|
||||
{ "internalType": "bytes32", "name": "s", "type": "bytes32" }
|
||||
],
|
||||
"name": "permit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address[]", "name": "target", "type": "address[]" }
|
||||
],
|
||||
"name": "removeFromAllowedList",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "contract IERC20",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{ "internalType": "address payable", "name": "_to", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "_balance", "type": "uint256" }
|
||||
],
|
||||
"name": "rescueTokens",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "bytes32", "name": "node", "type": "bytes32" }
|
||||
],
|
||||
"name": "resolve",
|
||||
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "recipient", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{ "internalType": "address", "name": "sender", "type": "address" },
|
||||
{ "internalType": "address", "name": "recipient", "type": "address" },
|
||||
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
181
test/utils.js
Normal file
181
test/utils.js
Normal file
@ -0,0 +1,181 @@
|
||||
const { ethers, network } = require("hardhat");
|
||||
const { time } = require("@nomicfoundation/hardhat-toolbox/network-helpers");
|
||||
|
||||
const stakingAddr = "0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29";
|
||||
const gasCompensationAddr = "0xFA4C1f3f7D5dd7c12a9Adb82Cd7dDA542E3d59ef";
|
||||
const userVaultAddr = "0x2F50508a8a3D323B91336FA3eA6ae50E55f32185";
|
||||
const governanceAddr = "0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce";
|
||||
const tornAddr = "0x77777FeDdddFfC19Ff86DB637967013e6C6A116C";
|
||||
|
||||
async function getManyEth(addr) {
|
||||
await network.provider.send("hardhat_setBalance", [addr, "0x111166630153555558483537"]);
|
||||
}
|
||||
|
||||
async function getPermitSignature(signer, tokenContract, spender, value, deadline) {
|
||||
const [nonce, name, version, chainId] = await Promise.all([
|
||||
tokenContract.nonces(signer.address),
|
||||
tokenContract.name(),
|
||||
"1",
|
||||
tokenContract.chainID(),
|
||||
]);
|
||||
|
||||
const domain = {
|
||||
name,
|
||||
version,
|
||||
chainId,
|
||||
verifyingContract: tornAddr,
|
||||
};
|
||||
const types = {
|
||||
Permit: [
|
||||
{
|
||||
name: "owner",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
name: "spender",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
name: "value",
|
||||
type: "uint256",
|
||||
},
|
||||
{
|
||||
name: "nonce",
|
||||
type: "uint256",
|
||||
},
|
||||
{
|
||||
name: "deadline",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
};
|
||||
const values = {
|
||||
owner: signer.address,
|
||||
spender,
|
||||
value,
|
||||
nonce,
|
||||
deadline,
|
||||
};
|
||||
|
||||
const signature = await signer.signTypedData(domain, types, values);
|
||||
return ethers.Signature.from(signature);
|
||||
}
|
||||
|
||||
async function resetStateBeforeProposal() {
|
||||
await network.provider.request({
|
||||
method: "hardhat_reset",
|
||||
params: [
|
||||
{
|
||||
forking: {
|
||||
jsonRpcUrl: config.networks.hardhat.forking.url,
|
||||
blockNumber: config.networks.hardhat.forking.blockNumber,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async function getTorn(signer) {
|
||||
return await ethers.getContractAt(require("./abi/torn.abi.json"), tornAddr, signer);
|
||||
}
|
||||
|
||||
async function getEnsRegistry() {
|
||||
const ensAddr = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e";
|
||||
return await ethers.getContractAt(require("./abi/ensRegistry.abi.json"), ensAddr);
|
||||
}
|
||||
|
||||
async function getEnsResolver(ensName) {
|
||||
const ensRegistry = await getEnsRegistry();
|
||||
const resolverAddr = await ensRegistry.resolver(ethers.namehash(ensName));
|
||||
return await ethers.getContractAt(require("./abi/ensResolver.abi.json"), resolverAddr);
|
||||
}
|
||||
|
||||
async function resolveAddr(ensName) {
|
||||
if (ethers.isAddress(ensName)) return ensName;
|
||||
const ensResolver = await getEnsResolver(ensName);
|
||||
|
||||
return await ensResolver.addr(ethers.namehash(ensName));
|
||||
}
|
||||
|
||||
async function getProxyImplAddr(proxyAddr) {
|
||||
const implementation = await ethers.provider.getStorage(
|
||||
proxyAddr,
|
||||
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
|
||||
);
|
||||
const [implementationAddr] = new ethers.AbiCoder().decode(["address"], implementation);
|
||||
|
||||
return implementationAddr;
|
||||
}
|
||||
|
||||
async function getGovernance(signer) {
|
||||
return await ethers.getContractAt(require("./abi/governance.abi.json"), governanceAddr, signer);
|
||||
}
|
||||
|
||||
async function getAirdrop(airdropAddr, signer) {
|
||||
return await ethers.getContractAt(require("./abi/airdrop.abi.json"), airdropAddr, signer);
|
||||
}
|
||||
|
||||
async function signerLockInGov(tornAmount, signer) {
|
||||
if (!signer) signer = (await ethers.getSigners())[0];
|
||||
|
||||
const governanceSigner = await ethers.getImpersonatedSigner(governanceAddr);
|
||||
const torn = await getTorn(governanceSigner);
|
||||
await torn.transfer(signer.address, tornAmount);
|
||||
await getManyEth(signer.address);
|
||||
const governance = await getGovernance(signer);
|
||||
const deadline = ethers.MaxUint256;
|
||||
const { v, r, s } = await getPermitSignature(signer, torn, governanceAddr, tornAmount, deadline);
|
||||
await governance.lock(signer.address, tornAmount, deadline, v, r, s);
|
||||
|
||||
return signer;
|
||||
}
|
||||
|
||||
async function executeNewProposal(proposalAddr) {
|
||||
const governance = await getGovernance();
|
||||
const quorum = await governance.QUORUM_VOTES();
|
||||
const stakerSigner = await signerLockInGov(quorum);
|
||||
const governanceContract = await getGovernance(stakerSigner);
|
||||
await governanceContract.propose(proposalAddr, "");
|
||||
const proposalId = await governanceContract.proposalCount();
|
||||
await time.increase(60 * 60);
|
||||
await governanceContract.castVote(proposalId, true);
|
||||
await time.increase(60 * 60 * 24 * 7 + 60);
|
||||
await governanceContract.execute(proposalId);
|
||||
await time.increase(60 * 60 * 24 * 4);
|
||||
await governanceContract.unlock(quorum);
|
||||
const torn = await getTorn(stakerSigner);
|
||||
await torn.transfer(governanceAddr, quorum);
|
||||
}
|
||||
|
||||
async function deployAndExecuteProposal() {
|
||||
const airdropFactory = await ethers.getContractFactory("SablierAirdrop");
|
||||
const airdrop = await airdropFactory.deploy();
|
||||
const airdropAddr = await airdrop.getAddress();
|
||||
|
||||
const proposalFactory = await ethers.getContractFactory("Proposal");
|
||||
const proposal = await proposalFactory.deploy(airdropAddr);
|
||||
const deployedProposalAddr = await proposal.getAddress();
|
||||
|
||||
await executeNewProposal(deployedProposalAddr);
|
||||
|
||||
const airdropContract = await getAirdrop(airdropAddr);
|
||||
return { airdropAddr, airdropContract };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
resetStateBeforeProposal,
|
||||
deployAndExecuteProposal,
|
||||
getGovernance,
|
||||
getEnsRegistry,
|
||||
getEnsResolver,
|
||||
resolveAddr,
|
||||
getProxyImplAddr,
|
||||
governanceAddr,
|
||||
getManyEth,
|
||||
tornAddr,
|
||||
getTorn,
|
||||
stakingAddr,
|
||||
getPermitSignature,
|
||||
signerLockInGov,
|
||||
executeNewProposal,
|
||||
};
|
Loading…
Reference in New Issue
Block a user