Skip to content

Commit

Permalink
Merge 85690ed into 67cb333
Browse files Browse the repository at this point in the history
  • Loading branch information
CJ42 authored Sep 27, 2023
2 parents 67cb333 + 85690ed commit 77c5f55
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 69 deletions.
108 changes: 68 additions & 40 deletions contracts/LSP7DigitalAsset/LSP7DigitalAssetCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -176,21 +176,12 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
) public virtual {
if (from == to) revert LSP7CannotSendToSelf();

// if the caller is an operator
if (msg.sender != from) {
uint256 operatorAmount = _operatorAuthorizedAmount[from][
msg.sender
];
if (amount > operatorAmount) {
revert LSP7AmountExceedsAuthorizedAmount(
from,
operatorAmount,
msg.sender,
amount
);
}

_updateOperator(from, msg.sender, operatorAmount - amount, "");
_spendAllowance({
operator: msg.sender,
tokenOwner: from,
amountToSpend: amount
});
}

_transfer(from, to, amount, force, data);
Expand Down Expand Up @@ -237,8 +228,8 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
* This is an alternative approach to {authorizeOperator} that can be used as a mitigation
* for the double spending allowance problem.
*
* @param operator the operator to increase the allowance for `msg.sender`
* @param addedAmount the additional amount to add on top of the current operator's allowance
* @param operator The operator to increase the allowance for `msg.sender`
* @param addedAmount The additional amount to add on top of the current operator's allowance
*
* @custom:requirements
* - `operator` cannot be the same address as `msg.sender`
Expand All @@ -253,6 +244,7 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
) public virtual {
uint256 newAllowance = authorizedAmountFor(operator, msg.sender) +
addedAmount;

_updateOperator(
msg.sender,
operator,
Expand Down Expand Up @@ -284,8 +276,8 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
* - {RevokeOperator} event if `subtractedAmount` is the full allowance,
* indicating `operator` does not have any alauthorizedAmountForlowance left for `msg.sender`.
*
* @param operator the operator to decrease allowance for `msg.sender`
* @param subtractedAmount the amount to decrease by in the operator's allowance.
* @param operator The operator to decrease allowance for `msg.sender`
* @param subtractedAmount The amount to decrease by in the operator's allowance.
*
* @custom:requirements
* - `operator` cannot be the zero address.
Expand Down Expand Up @@ -325,6 +317,10 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
* If the amount is zero the operator is removed from the list of operators, otherwise he is added to the list of operators.
* If the amount is zero then the operator is being revoked, otherwise the operator amount is being modified.
*
* @param tokenOwner The address that will give `operator` an allowance for on its balance.
* @param operator The address to grant an allowance to spend.
* @param allowance The maximum amount of token that `operator` can spend from the `tokenOwner`'s balance.
*
* @custom:events
* - {RevokedOperator} event when operator's allowance is set to `0`.
* - {AuthorizedOperator} event when operator's allowance is set to any other amount.
Expand All @@ -336,7 +332,7 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
function _updateOperator(
address tokenOwner,
address operator,
uint256 amount,
uint256 allowance,
bytes memory operatorNotificationData
) internal virtual {
if (operator == address(0)) {
Expand All @@ -347,14 +343,14 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
revert LSP7TokenOwnerCannotBeOperator();
}

_operatorAuthorizedAmount[tokenOwner][operator] = amount;
_operatorAuthorizedAmount[tokenOwner][operator] = allowance;

if (amount != 0) {
if (allowance != 0) {
_operators[tokenOwner].add(operator);
emit AuthorizedOperator(
operator,
tokenOwner,
amount,
allowance,
operatorNotificationData
);
} else {
Expand Down Expand Up @@ -440,24 +436,6 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
revert LSP7AmountExceedsBalance(balance, from, amount);
}

// if the caller is an operator
if (msg.sender != from) {
uint256 authorizedAmount = _operatorAuthorizedAmount[from][
msg.sender
];
if (amount > authorizedAmount) {
revert LSP7AmountExceedsAuthorizedAmount(
from,
authorizedAmount,
msg.sender,
amount
);
}
_operatorAuthorizedAmount[from][msg.sender] =
authorizedAmount -
amount;
}

_beforeTokenTransfer(from, address(0), amount);

// tokens being burnt
Expand All @@ -466,11 +444,61 @@ abstract contract LSP7DigitalAssetCore is ILSP7DigitalAsset {
_tokenOwnerBalances[from] -= amount;

emit Transfer(msg.sender, from, address(0), amount, false, data);
emit Transfer({
operator: msg.sender,
from: from,
to: address(0),
amount: amount,
force: false,
data: data
});

bytes memory lsp1Data = abi.encode(from, address(0), amount, data);
_notifyTokenSender(from, lsp1Data);
}

/**
* @dev Spend `amountToSpend` from the `operator`'s authorized on behalf of the `tokenOwner`.
*
* @param operator The address of the operator to decrease the allowance of.
* @param tokenOwner The address that granted an allowance on its balance to `operator`.
* @param amountToSpend The amount of tokens to substract in allowance of `operator`.
*
* @custom:events
* - {RevokedOperator} event when operator's allowance is set to `0`.
* - {AuthorizedOperator} event when operator's allowance is set to any other amount.
*
* @custom:requirements
* - The `amountToSpend` MUST be at least the allowance granted to `operator` (accessible via {`authorizedAmountFor}`)
* - `operator` cannot be the zero address.
* - `operator` cannot be the same address as `tokenOwner`.
*/
function _spendAllowance(
address operator,
address tokenOwner,
uint256 amountToSpend
) internal virtual {
uint256 authorizedAmount = _operatorAuthorizedAmount[tokenOwner][
operator
];

if (amountToSpend > authorizedAmount) {
revert LSP7AmountExceedsAuthorizedAmount(
tokenOwner,
authorizedAmount,
operator,
amountToSpend
);
}

_updateOperator({
tokenOwner: tokenOwner,
operator: operator,
allowance: authorizedAmount - amountToSpend,
operatorNotificationData: ""
});
}

/**
* @dev Transfer tokens from `from` to `to` by decreasing the balance of `from` by `-amount` and increasing the balance
* of `to` by `+amount`.
Expand Down
4 changes: 4 additions & 0 deletions contracts/LSP7DigitalAsset/extensions/LSP7Burnable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ abstract contract LSP7Burnable is LSP7DigitalAsset {
uint256 amount,
bytes memory data
) public virtual {
if (msg.sender != from) {
_spendAllowance(msg.sender, from, amount);
}

_burn(from, amount, data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ abstract contract LSP7BurnableInitAbstract is LSP7DigitalAssetInitAbstract {
uint256 amount,
bytes memory data
) public virtual {
if (msg.sender != from) {
_spendAllowance(msg.sender, from, amount);
}
_burn(from, amount, data);
}
}
41 changes: 36 additions & 5 deletions docs/contracts/LSP7DigitalAsset/LSP7DigitalAsset.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ Atomically decreases the allowance granted to `operator` by the caller. This is

| Name | Type | Description |
| -------------------------- | :-------: | ------------------------------------------------------ |
| `operator` | `address` | the operator to decrease allowance for `msg.sender` |
| `subtractedAmount` | `uint256` | the amount to decrease by in the operator's allowance. |
| `operator` | `address` | The operator to decrease allowance for `msg.sender` |
| `subtractedAmount` | `uint256` | The amount to decrease by in the operator's allowance. |
| `operatorNotificationData` | `bytes` | - |

<br/>
Expand Down Expand Up @@ -411,8 +411,8 @@ Atomically increases the allowance granted to `operator` by the caller. This is

| Name | Type | Description |
| -------------------------- | :-------: | ----------------------------------------------------------------------- |
| `operator` | `address` | the operator to increase the allowance for `msg.sender` |
| `addedAmount` | `uint256` | the additional amount to add on top of the current operator's allowance |
| `operator` | `address` | The operator to increase the allowance for `msg.sender` |
| `addedAmount` | `uint256` | The additional amount to add on top of the current operator's allowance |
| `operatorNotificationData` | `bytes` | - |

<br/>
Expand Down Expand Up @@ -811,7 +811,7 @@ Save gas by emitting the [`DataChanged`](#datachanged) event with only the first
function _updateOperator(
address tokenOwner,
address operator,
uint256 amount,
uint256 allowance,
bytes operatorNotificationData
) internal nonpayable;
```
Expand All @@ -820,6 +820,15 @@ Changes token `amount` the `operator` has access to from `tokenOwner` tokens.
If the amount is zero the operator is removed from the list of operators, otherwise he is added to the list of operators.
If the amount is zero then the operator is being revoked, otherwise the operator amount is being modified.

#### Parameters

| Name | Type | Description |
| -------------------------- | :-------: | -------------------------------------------------------------------------------------- |
| `tokenOwner` | `address` | The address that will give `operator` an allowance for on its balance. |
| `operator` | `address` | The address to grant an allowance to spend. |
| `allowance` | `uint256` | The maximum amount of token that `operator` can spend from the `tokenOwner`'s balance. |
| `operatorNotificationData` | `bytes` | - |

<br/>

### \_mint
Expand Down Expand Up @@ -890,6 +899,28 @@ Any logic in the [`_beforeTokenTransfer`](#_beforetokentransfer) function will r

<br/>

### \_spendAllowance

```solidity
function _spendAllowance(
address operator,
address tokenOwner,
uint256 amountToSpend
) internal nonpayable;
```

Spend `amountToSpend` from the `operator`'s authorized on behalf of the `tokenOwner`.

#### Parameters

| Name | Type | Description |
| --------------- | :-------: | ------------------------------------------------------------------- |
| `operator` | `address` | The address of the operator to decrease the allowance of. |
| `tokenOwner` | `address` | The address that granted an allowance on its balance to `operator`. |
| `amountToSpend` | `uint256` | The amount of tokens to substract in allowance of `operator`. |

<br/>

### \_transfer

```solidity
Expand Down
41 changes: 36 additions & 5 deletions docs/contracts/LSP7DigitalAsset/extensions/LSP7Burnable.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ Atomically decreases the allowance granted to `operator` by the caller. This is

| Name | Type | Description |
| -------------------------- | :-------: | ------------------------------------------------------ |
| `operator` | `address` | the operator to decrease allowance for `msg.sender` |
| `subtractedAmount` | `uint256` | the amount to decrease by in the operator's allowance. |
| `operator` | `address` | The operator to decrease allowance for `msg.sender` |
| `subtractedAmount` | `uint256` | The amount to decrease by in the operator's allowance. |
| `operatorNotificationData` | `bytes` | - |

<br/>
Expand Down Expand Up @@ -436,8 +436,8 @@ Atomically increases the allowance granted to `operator` by the caller. This is

| Name | Type | Description |
| -------------------------- | :-------: | ----------------------------------------------------------------------- |
| `operator` | `address` | the operator to increase the allowance for `msg.sender` |
| `addedAmount` | `uint256` | the additional amount to add on top of the current operator's allowance |
| `operator` | `address` | The operator to increase the allowance for `msg.sender` |
| `addedAmount` | `uint256` | The additional amount to add on top of the current operator's allowance |
| `operatorNotificationData` | `bytes` | - |

<br/>
Expand Down Expand Up @@ -836,7 +836,7 @@ Save gas by emitting the [`DataChanged`](#datachanged) event with only the first
function _updateOperator(
address tokenOwner,
address operator,
uint256 amount,
uint256 allowance,
bytes operatorNotificationData
) internal nonpayable;
```
Expand All @@ -845,6 +845,15 @@ Changes token `amount` the `operator` has access to from `tokenOwner` tokens.
If the amount is zero the operator is removed from the list of operators, otherwise he is added to the list of operators.
If the amount is zero then the operator is being revoked, otherwise the operator amount is being modified.

#### Parameters

| Name | Type | Description |
| -------------------------- | :-------: | -------------------------------------------------------------------------------------- |
| `tokenOwner` | `address` | The address that will give `operator` an allowance for on its balance. |
| `operator` | `address` | The address to grant an allowance to spend. |
| `allowance` | `uint256` | The maximum amount of token that `operator` can spend from the `tokenOwner`'s balance. |
| `operatorNotificationData` | `bytes` | - |

<br/>

### \_mint
Expand Down Expand Up @@ -915,6 +924,28 @@ Any logic in the [`_beforeTokenTransfer`](#_beforetokentransfer) function will r

<br/>

### \_spendAllowance

```solidity
function _spendAllowance(
address operator,
address tokenOwner,
uint256 amountToSpend
) internal nonpayable;
```

Spend `amountToSpend` from the `operator`'s authorized on behalf of the `tokenOwner`.

#### Parameters

| Name | Type | Description |
| --------------- | :-------: | ------------------------------------------------------------------- |
| `operator` | `address` | The address of the operator to decrease the allowance of. |
| `tokenOwner` | `address` | The address that granted an allowance on its balance to `operator`. |
| `amountToSpend` | `uint256` | The amount of tokens to substract in allowance of `operator`. |

<br/>

### \_transfer

```solidity
Expand Down
Loading

0 comments on commit 77c5f55

Please sign in to comment.