Skip to content

Instantly share code, notes, and snippets.

@auryn-macmillan
Last active October 7, 2020 21:38
Show Gist options
  • Save auryn-macmillan/197b777cd4380004811fb1c8c5e2e508 to your computer and use it in GitHub Desktop.
Save auryn-macmillan/197b777cd4380004811fb1c8c5e2e508 to your computer and use it in GitHub Desktop.
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