Last active
October 7, 2020 21:38
-
-
Save auryn-macmillan/197b777cd4380004811fb1c8c5e2e508 to your computer and use it in GitHub Desktop.
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
pragma solidity 0.7.2; | |
contract Delegator { | |
// struct that defines a delegate | |
struct Delegate { | |
// key is delegator address, value is the index of the delegators address in the delegators array | |
mapping (address => uint) delegatorIndex; | |
// array of addresses that delegate to this delegate. (heteronyms are confusing, lul) | |
address[] delegators; | |
} | |
// key is delegate address, value is delegate struct | |
mapping (address => Delegate) delegates; | |
// key is delegator address, value is delegate address | |
mapping (address => address) public delegation; | |
event delegated (address delegator, address delegatee); | |
event delegationRemoved (address delegator, address previousDelegatee); | |
// delegate to an address | |
function delegate (address addr) public { | |
require (addr != msg.sender, "can't delegate to self"); | |
require (addr != delegation[msg.sender], "already delegated to this address"); | |
require (addr != address(0), "can't delegate to 0x0"); | |
// check if addr is already delegating | |
if (delegation[msg.sender] != address(0)){ | |
removeDelegation(); | |
} | |
// add msg.sender to delegate's delegator array | |
delegates[addr].delegators.push(msg.sender); | |
// Update delegatorIndex | |
delegates[addr].delegatorIndex[msg.sender] = delegates[addr].delegators.length - 1; | |
// update delegation mapping | |
delegation[msg.sender] = addr; | |
emit delegated(msg.sender, addr); | |
} | |
function removeDelegation () public { | |
require (delegation[msg.sender] != address(0), "no delegate set"); | |
address delegateAddress = delegation[msg.sender]; | |
Delegate storage delegate = delegates[delegateAddress]; | |
uint delegatorIndex = delegate.delegatorIndex[msg.sender]; | |
// overwrite msg.sender's position in the array with the contents of the last element in array. | |
delegate.delegators[delegatorIndex] = delegate.delegators[delegate.delegators.length - 1]; | |
// correct the mapping for the element that was just moved | |
address tempAddr = delegate.delegators[delegatorIndex]; | |
delegate.delegatorIndex[tempAddr] = delegatorIndex; | |
// remove the last element in the array | |
delegate.delegators.pop(); | |
// set msg.sender's index to 0 | |
delegate.delegatorIndex[msg.sender] = 0; | |
// update delegation mapping | |
delegation[msg.sender] = address(0); | |
emit delegationRemoved(msg.sender, delegation[msg.sender]); | |
} | |
// return a array of addresses delegated to this address | |
function getDelegations (address addr) public view returns (address[] memory delegators) { | |
return delegates[addr].delegators; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment