// SPDX-License-Identifier: MIT pragma solidity ^0.7.1; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; interface Escrow { function getAddresses() external view returns(address[] memory); function balanceOf(address holder) external view returns(uint256); } abstract contract ERC20VotesEscrowed is ERC20Votes, Ownable { Escrow escrow; bool initialized = false; error AlreadyInitialized(); // to be called after tokens have been transferred to the escrow contract function setUpVotingPower(address _escrowAddress) external onlyOwner { if (initialized) revert AlreadyInitialized(); escrow = Escrow(_escrowAddress); address[] memory addresses = escrow.getAddresses(); for (uint i = 0; i < addresses.length; i++) { address a = addresses[i]; _jankyMoveVotingPower(_escrowAddress, a, escrow.balanceOf(a)); } initialized = true; } function _afterTokenTransfer(address _from, address _to, uint256 _amount) internal override { // if it's the escrow contract, don't transfer any voting power when it leaves escrow, the // power will remain with whoever it's been delegated to already if (address(escrow) != _from) { super._afterTokenTransfer(_from, _to, _amount); } } function _delegate(address delegator, address delegatee) internal override { super._delegate(delegator, delegatee); // adds the escrow balance to the new delegatee's voting power address currentDelegate = delegates(delegator); uint256 escrowBalance = escrow.balanceOf(delegator); _jankyMoveVotingPower(currentDelegate, delegatee, escrowBalance); } // Moves voting power with the normally private `_moveVotingPower` function // by calling the `_afterTokenTransfer` function. // // see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/dfef6a68ee18dbd2e1f5a099061a3b8a0e404485/contracts/token/ERC20/extensions/ERC20Votes.sol#LL217C6-L217C6 // see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/dfef6a68ee18dbd2e1f5a099061a3b8a0e404485/contracts/token/ERC20/ERC20.sol#L364 function _jankyMoveVotingPower(address _src, address _dst, uint256 _amount) internal { super._afterTokenTransfer(_src, _dst, _amount); } }
0.7.1