Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ERC777 operator the caller #2134

Merged
merged 3 commits into from
Mar 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
* `Escrow`, `ConditionalEscrow`, `RefundEscrow`: these now use `Ownable` instead of `Secondary`, their external API changed accordingly. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120))
* `ERC20`: removed `_burnFrom`. ([#2119](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2119))
* `Address`: removed `toPayable`, use `payable(address)` instead. ([#2133](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2133))
* `ERC777`: `_send`, `_mint` and `_burn` now use the caller as the operator. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134))
* `ERC777`: removed `_callsTokensToSend` and `_callTokensReceived`. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134))

## 2.5.0 (2020-02-04)

Expand Down
5 changes: 2 additions & 3 deletions contracts/mocks/ERC777Mock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@ contract ERC777Mock is Context, ERC777 {
string memory symbol,
address[] memory defaultOperators
) public ERC777(name, symbol, defaultOperators) {
_mint(_msgSender(), initialHolder, initialBalance, "", "");
_mint(initialHolder, initialBalance, "", "");
}

function mintInternal (
address operator,
address to,
uint256 amount,
bytes memory userData,
bytes memory operatorData
) public {
_mint(operator, to, amount, userData, operatorData);
_mint(to, amount, userData, operatorData);
}
}
23 changes: 12 additions & 11 deletions contracts/token/ERC777/ERC777.sol
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ contract ERC777 is Context, IERC777, IERC20 {
* Also emits a {IERC20-Transfer} event for ERC20 compatibility.
*/
function send(address recipient, uint256 amount, bytes memory data) public override {
_send(_msgSender(), _msgSender(), recipient, amount, data, "", true);
_send(_msgSender(), recipient, amount, data, "", true);
}

/**
Expand Down Expand Up @@ -166,7 +166,7 @@ contract ERC777 is Context, IERC777, IERC20 {
* Also emits a {IERC20-Transfer} event for ERC20 compatibility.
*/
function burn(uint256 amount, bytes memory data) public override {
_burn(_msgSender(), _msgSender(), amount, data, "");
_burn(_msgSender(), amount, data, "");
}

/**
Expand Down Expand Up @@ -233,7 +233,7 @@ contract ERC777 is Context, IERC777, IERC20 {
public override
{
require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder");
_send(_msgSender(), sender, recipient, amount, data, operatorData, true);
_send(sender, recipient, amount, data, operatorData, true);
}

/**
Expand All @@ -243,7 +243,7 @@ contract ERC777 is Context, IERC777, IERC20 {
*/
function operatorBurn(address account, uint256 amount, bytes memory data, bytes memory operatorData) public override {
require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder");
_burn(_msgSender(), account, amount, data, operatorData);
_burn(account, amount, data, operatorData);
}

/**
Expand Down Expand Up @@ -311,7 +311,6 @@ contract ERC777 is Context, IERC777, IERC20 {
* interface.
*/
function _mint(
address operator,
address account,
uint256 amount,
bytes memory userData,
Expand All @@ -321,6 +320,8 @@ contract ERC777 is Context, IERC777, IERC20 {
{
require(account != address(0), "ERC777: mint to the zero address");

address operator = _msgSender();

// Update state variables
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
Expand All @@ -333,7 +334,6 @@ contract ERC777 is Context, IERC777, IERC20 {

/**
* @dev Send tokens
* @param operator address operator requesting the transfer
* @param from address token holder address
* @param to address recipient address
* @param amount uint256 amount of tokens to transfer
Expand All @@ -342,7 +342,6 @@ contract ERC777 is Context, IERC777, IERC20 {
* @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
*/
function _send(
address operator,
address from,
address to,
uint256 amount,
Expand All @@ -355,6 +354,8 @@ contract ERC777 is Context, IERC777, IERC20 {
require(from != address(0), "ERC777: send from the zero address");
require(to != address(0), "ERC777: send to the zero address");

address operator = _msgSender();

_callTokensToSend(operator, from, to, amount, userData, operatorData);

_move(operator, from, to, amount, userData, operatorData);
Expand All @@ -364,14 +365,12 @@ contract ERC777 is Context, IERC777, IERC20 {

/**
* @dev Burn tokens
* @param operator address operator requesting the operation
* @param from address token holder address
* @param amount uint256 amount of tokens to burn
* @param data bytes extra information provided by the token holder
* @param operatorData bytes extra information provided by the operator (if any)
*/
function _burn(
address operator,
address from,
uint256 amount,
bytes memory data,
Expand All @@ -381,6 +380,8 @@ contract ERC777 is Context, IERC777, IERC20 {
{
require(from != address(0), "ERC777: burn from the zero address");

address operator = _msgSender();

_callTokensToSend(operator, from, address(0), amount, data, operatorData);

// Update state variables
Expand Down Expand Up @@ -437,7 +438,7 @@ contract ERC777 is Context, IERC777, IERC20 {
bytes memory userData,
bytes memory operatorData
)
internal
private
{
address implementer = ERC1820_REGISTRY.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);
if (implementer != address(0)) {
Expand Down Expand Up @@ -465,7 +466,7 @@ contract ERC777 is Context, IERC777, IERC20 {
bytes memory operatorData,
bool requireReceptionAck
)
internal
private
{
address implementer = ERC1820_REGISTRY.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);
if (implementer != address(0)) {
Expand Down
10 changes: 6 additions & 4 deletions test/token/ERC777/ERC777.behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,9 @@ function shouldBehaveLikeERC777InternalMint (recipient, operator, amount, data,
shouldInternalMintTokens(operator, recipient, amount, data, operatorData);

it('reverts when minting tokens for the zero address', async function () {
await expectRevert.unspecified(this.token.mintInternal(operator, ZERO_ADDRESS, amount, data, operatorData));
await expectRevert.unspecified(
this.token.mintInternal(ZERO_ADDRESS, amount, data, operatorData, { from: operator })
);
});
}

Expand All @@ -290,7 +292,7 @@ function shouldInternalMintTokens (operator, to, amount, data, operatorData) {
const initialTotalSupply = await this.token.totalSupply();
const initialToBalance = await this.token.balanceOf(to);

const { logs } = await this.token.mintInternal(operator, to, amount, data, operatorData);
const { logs } = await this.token.mintInternal(to, amount, data, operatorData, { from: operator });

expectEvent.inLogs(logs, 'Minted', {
operator,
Expand Down Expand Up @@ -332,7 +334,7 @@ function shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook (operator, am

it('mint (internal) reverts', async function () {
await expectRevert.unspecified(
this.token.mintInternal(operator, this.recipient, amount, data, operatorData)
this.token.mintInternal(this.recipient, amount, data, operatorData, { from: operator })
);
});
});
Expand Down Expand Up @@ -387,7 +389,7 @@ function shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook (operator, am

it('TokensRecipient receives mint (internal) data and is called after state mutation', async function () {
const { tx } = await this.token.mintInternal(
operator, this.recipient, amount, data, operatorData,
this.recipient, amount, data, operatorData, { from: operator }
);

const postRecipientBalance = await this.token.balanceOf(this.recipient);
Expand Down
2 changes: 1 addition & 1 deletion test/token/ERC777/ERC777.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ describe('ERC777', function () {

it('mint (internal) reverts', async function () {
await expectRevert(
this.token.mintInternal(operator, this.recipient, amount, data, operatorData),
this.token.mintInternal(this.recipient, amount, data, operatorData, { from: operator }),
'ERC777: token recipient contract has no implementer for ERC777TokensRecipient',
);
});
Expand Down