Skip to content

Commit

Permalink
Emit DelegateVotesChanged events after Transfer (#2733)
Browse files Browse the repository at this point in the history
  • Loading branch information
Amxx committed Jun 22, 2021
1 parent 4d0f8c1 commit 8a775cd
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
28 changes: 27 additions & 1 deletion contracts/token/ERC20/ERC20.sol
Expand Up @@ -234,6 +234,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
_balances[recipient] += amount;

emit Transfer(sender, recipient, amount);

_afterTokenTransfer(sender, recipient, amount);
}

/** @dev Creates `amount` tokens and assigns them to `account`, increasing
Expand All @@ -253,6 +255,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);

_afterTokenTransfer(address(0), account, amount);
}

/**
Expand All @@ -279,6 +283,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
_totalSupply -= amount;

emit Transfer(account, address(0), amount);

_afterTokenTransfer(account, address(0), amount);
}

/**
Expand Down Expand Up @@ -313,7 +319,7 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
Expand All @@ -325,4 +331,24 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
address to,
uint256 amount
) internal virtual {}

/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
4 changes: 3 additions & 1 deletion contracts/token/ERC20/extensions/ERC20Votes.sol
Expand Up @@ -190,11 +190,13 @@ abstract contract ERC20Votes is ERC20Permit {
*
* Emits a {DelegateVotesChanged} event.
*/
function _beforeTokenTransfer(
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual override {
super._afterTokenTransfer(from, to, amount);

_moveVotingPower(delegates(from), delegates(to), amount);
}

Expand Down
9 changes: 9 additions & 0 deletions test/token/ERC20/extensions/ERC20Votes.test.js
Expand Up @@ -306,6 +306,9 @@ contract('ERC20Votes', function (accounts) {
expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' });
expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) });

const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer');
expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true);

this.holderVotes = supply.subn(1);
this.recipientVotes = '0';
});
Expand All @@ -317,6 +320,9 @@ contract('ERC20Votes', function (accounts) {
expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' });
expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' });

const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer');
expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true);

this.holderVotes = '0';
this.recipientVotes = '1';
});
Expand All @@ -330,6 +336,9 @@ contract('ERC20Votes', function (accounts) {
expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) });
expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' });

const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer');
expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true);

this.holderVotes = supply.subn(1);
this.recipientVotes = '1';
});
Expand Down

0 comments on commit 8a775cd

Please sign in to comment.