This repository was archived by the owner on May 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 23
ETH Delegating #483
Merged
Merged
ETH Delegating #483
Changes from all commits
Commits
Show all changes
59 commits
Select commit
Hold shift + click to select a range
e63faeb
ETH bonding contract
nkuba 32ee0d4
ETH staking contract
nkuba 48f2384
Added tests for ETH bonding and staking contracts
nkuba 865b0a4
Added todo about initialization period
nkuba d6ae3f7
Updated visibility to match abstract contract
nkuba 531690b
Updated events emitted on ETH stake
nkuba 4112c05
Renamed ETHBonding to EthBonding
nkuba 3a5636c
Renamed ETHStaking to EthDelegating
nkuba f252f4f
Renamed stake to delegate
nkuba 6c71cea
Renamed _from to owner
nkuba 2479778
Expect contract typed addresses in constructors
nkuba c61e18c
Combined EthDelegating into EthBonding
nkuba 07e5ddb
Added EthBonding to deployment script
nkuba a8f4489
Initialization period for ETH-only delegation
nkuba aab2b89
Require minimum ETH value passed on delegation
nkuba 4a75c11
Added getDelegationInfo
nkuba b98050a
Renamed EthBonding to FullyBackedBonding
nkuba fd99459
Updated order of imports
nkuba 6bf2f6a
Moved FullyBackedBonding contract to dedicated directory
nkuba 04c8d25
Initial version of FullyBackedBondedECDSAKeep
nkuba 7533b4a
Initial version of FullyBackedBondedECDSAKeepFactory
nkuba 20c375e
Renamed EthBondingTest.js
nkuba 81be402
Added unit tests for FullyBacked keep and bonding
nkuba 7c3d0aa
Added fully backed contracts to migrations scripts
nkuba 0079c13
Claim delegated authority in Fully Backed keep contract
nkuba d5d6703
Added missing import in Keep Factory contract
nkuba c2fc5ef
Minor improvements to docs
nkuba 360486f
Lock bonding withdraw just after delegation
nkuba d65a096
Merge branch 'master' into eth-bonding
pdyraga 742d3cf
Refer to the most recent pre versions of keep dependencies
pdyraga a9cb6f3
Project version for contracts set to 1.3.0-pre.0
pdyraga 80c6e49
Revert "Expect contract typed addresses in constructors"
nkuba 26eea9d
Removed comment about clone removal
nkuba cc58f14
Renamed FullyBackedBondedECDSAKeep to FullyBackedECDSAKeep
nkuba 1e088d8
Confirmed bondWeightDivisor to 1 ETH
nkuba c04038b
Increased DELEGATION_LOCK_PERIOD to 2 weeks
nkuba c8dc76e
Updated delegation lock period hardcoded in test
nkuba 85c3663
Include delegation value in OperatorDelegated event
nkuba 566cc48
Set minimum delegation deposit to 40 ETH
nkuba a1ea59b
Decided on 20 ETH as minimum bond value
nkuba e4c9d82
Improved time increase value in test
nkuba ff5008c
Updated delegation lock period to 12 hours
nkuba 0c0475a
Improved docs around fully backed bonding
nkuba ae34de4
Cleaned up truffle deploy script
nkuba 25c6a4d
Assert createdAt and undelegatedAt in delegation test
nkuba faca5bd
Cleaned truffle init script
nkuba 03daf5f
Removed not used addKeep function from test stubs
nkuba 196880a
Improved time increase margin in tests
nkuba d1edab3
Merge remote-tracking branch 'origin/master' into eth-bonding
nkuba ee9a30b
Removed not needed TODO comment in test
nkuba 65186c9
Very minor improvements to tests
nkuba b92218c
Get delegation lock period from contract in tests
nkuba 766a841
Removed not needed call in initialization script
nkuba 8a4ff82
Defined ini period in truffle deployment script
nkuba 3778ae1
Added tests for operator updates
nkuba cf0127c
Added top up function to Fully Backed Bonding contract
nkuba 102ce15
Fixed failing test
nkuba dc04021
Replaced before with beforeEach for topUp test
nkuba f9f719a
Added details to topup documentation
nkuba File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,210 @@ | ||
| /** | ||
| ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄ | ||
| ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀ | ||
| ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ | ||
| ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ | ||
|
|
||
| Trust math, not hardware. | ||
| */ | ||
|
|
||
| pragma solidity 0.5.17; | ||
|
|
||
| import "../AbstractBonding.sol"; | ||
|
|
||
| import "@keep-network/keep-core/contracts/Authorizations.sol"; | ||
| import "@keep-network/keep-core/contracts/StakeDelegatable.sol"; | ||
| import "@keep-network/keep-core/contracts/KeepRegistry.sol"; | ||
|
|
||
| import "@keep-network/sortition-pools/contracts/api/IFullyBackedBonding.sol"; | ||
|
|
||
| /// @title Fully Backed Bonding | ||
| /// @notice Contract holding deposits and delegations for ETH-only keeps' | ||
| /// operators. An owner of the ETH can delegate ETH to an operator by depositing | ||
| /// it in this contract. | ||
| contract FullyBackedBonding is | ||
| IFullyBackedBonding, | ||
| AbstractBonding, | ||
| Authorizations, | ||
| StakeDelegatable | ||
| { | ||
| event Delegated(address indexed owner, address indexed operator); | ||
|
|
||
| event OperatorDelegated( | ||
| address indexed operator, | ||
| address indexed beneficiary, | ||
| address indexed authorizer, | ||
| uint256 value | ||
| ); | ||
|
|
||
| event OperatorToppedUp(address indexed operator, uint256 value); | ||
|
|
||
| // The ether value (in wei) that should be passed along with the delegation | ||
| // and deposited for bonding. | ||
| uint256 public constant MINIMUM_DELEGATION_DEPOSIT = 40 ether; | ||
|
|
||
| // Once a delegation to an operator is received the delegator has to wait for | ||
| // specific time period before being able to pull out the funds. | ||
| uint256 public constant DELEGATION_LOCK_PERIOD = 12 hours; | ||
|
|
||
| uint256 public initializationPeriod; // varies between mainnet and testnet | ||
|
|
||
| /// @notice Initializes Fully Backed Bonding contract. | ||
| /// @param _keepRegistry Keep Registry contract address. | ||
| /// @param _initializationPeriod To avoid certain attacks on group selection, | ||
| /// recently delegated operators must wait for a specific period of time | ||
| /// before being eligible for group selection. | ||
| constructor(KeepRegistry _keepRegistry, uint256 _initializationPeriod) | ||
| public | ||
| AbstractBonding(address(_keepRegistry)) | ||
| Authorizations(_keepRegistry) | ||
| { | ||
| initializationPeriod = _initializationPeriod; | ||
| } | ||
|
|
||
| /// @notice Registers delegation details. The function is used to register | ||
| /// addresses of operator, beneficiary and authorizer for a delegation from | ||
| /// the caller. | ||
| /// The function requires ETH to be submitted in the call as a protection | ||
| /// against attacks blocking operators. The value should be at least equal | ||
| /// to the minimum delegation deposit. Whole amount is deposited as operator's | ||
| /// unbonded value for the future bonding. | ||
| /// @param operator Address of the operator. | ||
| /// @param beneficiary Address of the beneficiary. | ||
| /// @param authorizer Address of the authorizer. | ||
| function delegate( | ||
| address operator, | ||
| address payable beneficiary, | ||
| address authorizer | ||
| ) external payable { | ||
| address owner = msg.sender; | ||
|
|
||
| require( | ||
| operators[operator].owner == address(0), | ||
| "Operator already in use" | ||
| ); | ||
|
|
||
| require( | ||
| msg.value >= MINIMUM_DELEGATION_DEPOSIT, | ||
| "Insufficient delegation value" | ||
| ); | ||
|
|
||
| operators[operator] = Operator( | ||
| OperatorParams.pack(0, block.timestamp, 0), | ||
| owner, | ||
| beneficiary, | ||
| authorizer | ||
| ); | ||
|
|
||
| deposit(operator); | ||
|
|
||
| emit Delegated(owner, operator); | ||
| emit OperatorDelegated(operator, beneficiary, authorizer, msg.value); | ||
| } | ||
|
|
||
| /// @notice Top-ups operator's unbonded value. | ||
| /// @dev This function should be used to add new unbonded value to the system | ||
| /// for an operator. The `deposit` function defined in parent abstract contract | ||
| /// should be called only by applications returning value that has been already | ||
| /// initially deposited and seized later. As an application may seize bonds | ||
| /// and return them to the bonding contract with `deposit` function it makes | ||
| /// tracking the totally deposited value much more complicated. Functions | ||
| /// `delegate` and `topUps` should be used to add fresh value to the contract | ||
| /// and events emitted by these functions should be enough to determine total | ||
| /// value deposited ever for an operator. | ||
| /// @param operator Address of the operator. | ||
| function topUp(address operator) public payable { | ||
| deposit(operator); | ||
|
|
||
| emit OperatorToppedUp(operator, msg.value); | ||
| } | ||
|
|
||
| /// @notice Checks if the operator for the given bond creator contract | ||
| /// has passed the initialization period. | ||
| /// @param operator The operator address. | ||
| /// @param bondCreator The bond creator contract address. | ||
| /// @return True if operator has passed initialization period for given | ||
| /// bond creator contract, false otherwise. | ||
| function isInitialized(address operator, address bondCreator) | ||
| public | ||
| view | ||
| returns (bool) | ||
| { | ||
| uint256 operatorParams = operators[operator].packedParams; | ||
|
|
||
| return | ||
| isAuthorizedForOperator(operator, bondCreator) && | ||
| _isInitialized(operatorParams); | ||
| } | ||
|
|
||
| /// @notice Withdraws amount from operator's value available for bonding. | ||
| /// This function can be called only by: | ||
| /// - operator, | ||
| /// - owner of the stake. | ||
| /// Withdraw cannot be performed immediately after delegation to protect | ||
| /// from a griefing. It is required that delegator waits specific period | ||
| /// of time before they can pull out the funds deposited on delegation. | ||
| /// @param amount Value to withdraw in wei. | ||
| /// @param operator Address of the operator. | ||
| function withdraw(uint256 amount, address operator) public { | ||
| require( | ||
| msg.sender == operator || msg.sender == ownerOf(operator), | ||
| "Only operator or the owner is allowed to withdraw bond" | ||
| ); | ||
|
|
||
| require( | ||
| hasDelegationLockPassed(operator), | ||
| "Delegation lock period has not passed yet" | ||
| ); | ||
|
|
||
| withdrawBond(amount, operator); | ||
| } | ||
|
|
||
| /// @notice Gets delegation info for the given operator. | ||
| /// @param operator Address of the operator. | ||
| /// @return createdAt The time when the delegation was created. | ||
| /// @return undelegatedAt The time when undelegation has been requested. | ||
| /// If undelegation has not been requested, 0 is returned. | ||
| function getDelegationInfo(address operator) | ||
| public | ||
| view | ||
| returns (uint256 createdAt, uint256 undelegatedAt) | ||
| { | ||
| uint256 operatorParams = operators[operator].packedParams; | ||
|
|
||
| return ( | ||
| operatorParams.getCreationTimestamp(), | ||
| operatorParams.getUndelegationTimestamp() | ||
| ); | ||
| } | ||
|
|
||
| /// @notice Is the operator with the given params initialized | ||
| function _isInitialized(uint256 operatorParams) | ||
| internal | ||
| view | ||
| returns (bool) | ||
| { | ||
| return | ||
| block.timestamp > | ||
| operatorParams.getCreationTimestamp().add(initializationPeriod); | ||
| } | ||
|
|
||
| /// @notice Has lock period passed for a delegation. | ||
| /// @param operator Address of the operator. | ||
| /// @return True if delegation lock period passed, false otherwise. | ||
| function hasDelegationLockPassed(address operator) | ||
| internal | ||
| view | ||
| returns (bool) | ||
| { | ||
| return | ||
| block.timestamp > | ||
| operators[operator].packedParams.getCreationTimestamp().add( | ||
| DELEGATION_LOCK_PERIOD | ||
| ); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| /** | ||
| ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄ | ||
| ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓ ▐▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▄▄▄▄ ▓▓▓▓▓▓▄▄▄▄ ▐▓▓▓▓▓▌ ▐▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓▓▓▓▓▓▓▓▀ ▐▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓▀▀▀▀ ▓▓▓▓▓▓▀▀▀▀ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀ | ||
| ▓▓▓▓▓▓ ▀▓▓▓▓▓▓▄ ▐▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▐▓▓▓▓▓▌ | ||
| ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ | ||
| ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ | ||
|
|
||
| Trust math, not hardware. | ||
| */ | ||
|
|
||
| pragma solidity 0.5.17; | ||
|
|
||
| import "../AbstractBondedECDSAKeep.sol"; | ||
| import "./FullyBackedBonding.sol"; | ||
| import "./FullyBackedECDSAKeepFactory.sol"; | ||
|
|
||
| /// @title Fully Backed Bonded ECDSA Keep | ||
| /// @notice ECDSA keep with additional signer bond requirement that is fully backed | ||
| /// by ETH only. | ||
| /// @dev This contract is used as a master contract for clone factory in | ||
| /// BondedECDSAKeepFactory as per EIP-1167. | ||
| contract FullyBackedECDSAKeep is AbstractBondedECDSAKeep { | ||
| FullyBackedBonding bonding; | ||
| FullyBackedECDSAKeepFactory keepFactory; | ||
|
|
||
| /// @notice Initialization function. | ||
| /// @dev We use clone factory to create new keep. That is why this contract | ||
| /// doesn't have a constructor. We provide keep parameters for each instance | ||
| /// function after cloning instances from the master contract. | ||
| /// @param _owner Address of the keep owner. | ||
| /// @param _members Addresses of the keep members. | ||
| /// @param _honestThreshold Minimum number of honest keep members. | ||
| /// @param _bonding Address of the Bonding contract. | ||
| /// @param _keepFactory Address of the BondedECDSAKeepFactory that created | ||
| /// this keep. | ||
| function initialize( | ||
| address _owner, | ||
| address[] memory _members, | ||
| uint256 _honestThreshold, | ||
| address _bonding, | ||
| address payable _keepFactory | ||
| ) public { | ||
| super.initialize(_owner, _members, _honestThreshold, _bonding); | ||
|
|
||
| bonding = FullyBackedBonding(_bonding); | ||
| keepFactory = FullyBackedECDSAKeepFactory(_keepFactory); | ||
|
|
||
| bonding.claimDelegatedAuthority(_keepFactory); | ||
| } | ||
|
|
||
| function slashForSignatureFraud() internal { | ||
| // TODO: We don't need to do anything as keep owner is able to seize the bonds | ||
| // TODO: Ban members (remove from sortition pool and don't let to rejoin) | ||
| } | ||
|
|
||
| /// @notice Gets the beneficiary for the specified member address. | ||
| /// @param _member Member address. | ||
| /// @return Beneficiary address. | ||
| function beneficiaryOf(address _member) | ||
| internal | ||
| view | ||
| returns (address payable) | ||
| { | ||
| return bonding.beneficiaryOf(_member); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.