Skip to content

Commit

Permalink
Merge branch 'main' into BTT-drop-1155
Browse files Browse the repository at this point in the history
  • Loading branch information
joaquim-verges authored Oct 16, 2023
2 parents 315e923 + 3f4076e commit 793c67b
Show file tree
Hide file tree
Showing 24 changed files with 1,195 additions and 11 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ jobs:
run: |
forge coverage --report lcov
lcov --remove lcov.info -o lcov.info 'src/test/**'
lcov --remove lcov.info -o lcov.info 'contracts/external-deps/**'
lcov --remove lcov.info -o lcov.info 'contracts/eip/**'
forge test
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
Expand Down
11 changes: 8 additions & 3 deletions contracts/extension/BurnToClaim.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ abstract contract BurnToClaim is IBurnToClaim {

function setBurnToClaimInfo(BurnToClaimInfo calldata _burnToClaimInfo) external virtual {
require(_canSetBurnToClaim(), "Not authorized.");
require(_burnToClaimInfo.originContractAddress != address(0), "Origin contract not set.");
require(_burnToClaimInfo.currency != address(0), "Currency not set.");

burnToClaimInfo = _burnToClaimInfo;
}
Expand All @@ -30,12 +32,15 @@ abstract contract BurnToClaim is IBurnToClaim {

if (_burnToClaimInfo.tokenType == IBurnToClaim.TokenType.ERC721) {
require(_quantity == 1, "Invalid amount");
require(IERC721(_burnToClaimInfo.originContractAddress).ownerOf(_tokenId) == _tokenOwner);
require(IERC721(_burnToClaimInfo.originContractAddress).ownerOf(_tokenId) == _tokenOwner, "!Owner");
} else if (_burnToClaimInfo.tokenType == IBurnToClaim.TokenType.ERC1155) {
uint256 _eligible1155TokenId = _burnToClaimInfo.tokenId;

require(_tokenId == _eligible1155TokenId || _eligible1155TokenId == type(uint256).max);
require(IERC1155(_burnToClaimInfo.originContractAddress).balanceOf(_tokenOwner, _tokenId) >= _quantity);
require(_tokenId == _eligible1155TokenId, "Invalid token Id");
require(
IERC1155(_burnToClaimInfo.originContractAddress).balanceOf(_tokenOwner, _tokenId) >= _quantity,
"!Balance"
);
}

// TODO: check if additional verification steps are required / override in main contract
Expand Down
5 changes: 4 additions & 1 deletion contracts/extension/PlatformFee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ abstract contract PlatformFee is IPlatformFee {
return (platformFeeRecipient, flatPlatformFee);
}

/// @dev Returns the platform fee bps and recipient.
/// @dev Returns the platform fee type.
function getPlatformFeeType() public view returns (PlatformFeeType) {
return platformFeeType;
}
Expand All @@ -61,6 +61,9 @@ abstract contract PlatformFee is IPlatformFee {
if (_platformFeeBps > 10_000) {
revert("Exceeds max bps");
}
if (_platformFeeRecipient == address(0)) {
revert("Invalid recipient");
}

platformFeeBps = uint16(_platformFeeBps);
platformFeeRecipient = _platformFeeRecipient;
Expand Down
3 changes: 3 additions & 0 deletions contracts/extension/PrimarySale.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ abstract contract PrimarySale is IPrimarySale {

/// @dev Lets a contract admin set the recipient for all primary sales.
function _setupPrimarySaleRecipient(address _saleRecipient) internal {
if (_saleRecipient == address(0)) {
revert("Invalid recipient");
}
recipient = _saleRecipient;
emit PrimarySaleRecipientUpdated(_saleRecipient);
}
Expand Down
46 changes: 46 additions & 0 deletions contracts/extension/upgradeable/PlatformFee.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ library PlatformFeeStorage {
address platformFeeRecipient;
/// @dev The % of primary sales collected as platform fees.
uint16 platformFeeBps;
/// @dev Fee type variants: percentage fee and flat fee
IPlatformFee.PlatformFeeType platformFeeType;
/// @dev The flat amount collected by the contract as fees on primary sales.
uint256 flatPlatformFee;
}

function data() internal pure returns (Data storage data_) {
Expand All @@ -44,6 +48,16 @@ abstract contract PlatformFee is IPlatformFee {
return (_platformFeeStorage().platformFeeRecipient, uint16(_platformFeeStorage().platformFeeBps));
}

/// @dev Returns the platform fee bps and recipient.
function getFlatPlatformFeeInfo() public view returns (address, uint256) {
return (_platformFeeStorage().platformFeeRecipient, _platformFeeStorage().flatPlatformFee);
}

/// @dev Returns the platform fee type.
function getPlatformFeeType() public view returns (PlatformFeeType) {
return _platformFeeStorage().platformFeeType;
}

/**
* @notice Updates the platform fee recipient and bps.
* @dev Caller should be authorized to set platform fee info.
Expand Down Expand Up @@ -75,6 +89,38 @@ abstract contract PlatformFee is IPlatformFee {
emit PlatformFeeInfoUpdated(_platformFeeRecipient, _platformFeeBps);
}

/// @notice Lets a module admin set a flat fee on primary sales.
function setFlatPlatformFeeInfo(address _platformFeeRecipient, uint256 _flatFee) external {
if (!_canSetPlatformFeeInfo()) {
revert("Not authorized");
}

_setupFlatPlatformFeeInfo(_platformFeeRecipient, _flatFee);
}

/// @dev Sets a flat fee on primary sales.
function _setupFlatPlatformFeeInfo(address _platformFeeRecipient, uint256 _flatFee) internal {
_platformFeeStorage().flatPlatformFee = _flatFee;
_platformFeeStorage().platformFeeRecipient = _platformFeeRecipient;

emit FlatPlatformFeeUpdated(_platformFeeRecipient, _flatFee);
}

/// @notice Lets a module admin set platform fee type.
function setPlatformFeeType(PlatformFeeType _feeType) external {
if (!_canSetPlatformFeeInfo()) {
revert("Not authorized");
}
_setupPlatformFeeType(_feeType);
}

/// @dev Sets platform fee type.
function _setupPlatformFeeType(PlatformFeeType _feeType) internal {
_platformFeeStorage().platformFeeType = _feeType;

emit PlatformFeeTypeUpdated(_feeType);
}

/// @dev Returns the PlatformFee storage.
function _platformFeeStorage() internal pure returns (PlatformFeeStorage.Data storage data) {
data = PlatformFeeStorage.data();
Expand Down
105 changes: 105 additions & 0 deletions contracts/legacy-contracts/extension/PlatformFee_V1.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

/// @author thirdweb

import "./interface/IPlatformFee_V1.sol";

/**
* @title Platform Fee
* @notice Thirdweb's `PlatformFee` is a contract extension to be used with any base contract. It exposes functions for setting and reading
* the recipient of platform fee and the platform fee basis points, and lets the inheriting contract perform conditional logic
* that uses information about platform fees, if desired.
*/

abstract contract PlatformFee is IPlatformFee {
/// @dev The address that receives all platform fees from all sales.
address private platformFeeRecipient;

/// @dev The % of primary sales collected as platform fees.
uint16 private platformFeeBps;

/// @dev Fee type variants: percentage fee and flat fee
PlatformFeeType private platformFeeType;

/// @dev The flat amount collected by the contract as fees on primary sales.
uint256 private flatPlatformFee;

/// @dev Returns the platform fee recipient and bps.
function getPlatformFeeInfo() public view override returns (address, uint16) {
return (platformFeeRecipient, uint16(platformFeeBps));
}

/// @dev Returns the platform fee bps and recipient.
function getFlatPlatformFeeInfo() public view returns (address, uint256) {
return (platformFeeRecipient, flatPlatformFee);
}

/// @dev Returns the platform fee bps and recipient.
function getPlatformFeeType() public view returns (PlatformFeeType) {
return platformFeeType;
}

/**
* @notice Updates the platform fee recipient and bps.
* @dev Caller should be authorized to set platform fee info.
* See {_canSetPlatformFeeInfo}.
* Emits {PlatformFeeInfoUpdated Event}; See {_setupPlatformFeeInfo}.
*
* @param _platformFeeRecipient Address to be set as new platformFeeRecipient.
* @param _platformFeeBps Updated platformFeeBps.
*/
function setPlatformFeeInfo(address _platformFeeRecipient, uint256 _platformFeeBps) external override {
if (!_canSetPlatformFeeInfo()) {
revert("Not authorized");
}
_setupPlatformFeeInfo(_platformFeeRecipient, _platformFeeBps);
}

/// @dev Sets the platform fee recipient and bps
function _setupPlatformFeeInfo(address _platformFeeRecipient, uint256 _platformFeeBps) internal {
if (_platformFeeBps > 10_000) {
revert("Exceeds max bps");
}

platformFeeBps = uint16(_platformFeeBps);
platformFeeRecipient = _platformFeeRecipient;

emit PlatformFeeInfoUpdated(_platformFeeRecipient, _platformFeeBps);
}

/// @notice Lets a module admin set a flat fee on primary sales.
function setFlatPlatformFeeInfo(address _platformFeeRecipient, uint256 _flatFee) external {
if (!_canSetPlatformFeeInfo()) {
revert("Not authorized");
}

_setupFlatPlatformFeeInfo(_platformFeeRecipient, _flatFee);
}

/// @dev Sets a flat fee on primary sales.
function _setupFlatPlatformFeeInfo(address _platformFeeRecipient, uint256 _flatFee) internal {
flatPlatformFee = _flatFee;
platformFeeRecipient = _platformFeeRecipient;

emit FlatPlatformFeeUpdated(_platformFeeRecipient, _flatFee);
}

/// @notice Lets a module admin set platform fee type.
function setPlatformFeeType(PlatformFeeType _feeType) external {
if (!_canSetPlatformFeeInfo()) {
revert("Not authorized");
}
_setupPlatformFeeType(_feeType);
}

/// @dev Sets platform fee type.
function _setupPlatformFeeType(PlatformFeeType _feeType) internal {
platformFeeType = _feeType;

emit PlatformFeeTypeUpdated(_feeType);
}

/// @dev Returns whether platform fee info can be set in the given execution context.
function _canSetPlatformFeeInfo() internal view virtual returns (bool);
}
47 changes: 47 additions & 0 deletions contracts/legacy-contracts/extension/PrimarySale_V1.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

/// @author thirdweb

import "./interface/IPrimarySale_V1.sol";

/**
* @title Primary Sale
* @notice Thirdweb's `PrimarySale` is a contract extension to be used with any base contract. It exposes functions for setting and reading
* the recipient of primary sales, and lets the inheriting contract perform conditional logic that uses information about
* primary sales, if desired.
*/

abstract contract PrimarySale is IPrimarySale {
/// @dev The address that receives all primary sales value.
address private recipient;

/// @dev Returns primary sale recipient address.
function primarySaleRecipient() public view override returns (address) {
return recipient;
}

/**
* @notice Updates primary sale recipient.
* @dev Caller should be authorized to set primary sales info.
* See {_canSetPrimarySaleRecipient}.
* Emits {PrimarySaleRecipientUpdated Event}; See {_setupPrimarySaleRecipient}.
*
* @param _saleRecipient Address to be set as new recipient of primary sales.
*/
function setPrimarySaleRecipient(address _saleRecipient) external override {
if (!_canSetPrimarySaleRecipient()) {
revert("Not authorized");
}
_setupPrimarySaleRecipient(_saleRecipient);
}

/// @dev Lets a contract admin set the recipient for all primary sales.
function _setupPrimarySaleRecipient(address _saleRecipient) internal {
recipient = _saleRecipient;
emit PrimarySaleRecipientUpdated(_saleRecipient);
}

/// @dev Returns whether primary sale recipient can be set in the given execution context.
function _canSetPrimarySaleRecipient() internal view virtual returns (bool);
}
33 changes: 33 additions & 0 deletions contracts/legacy-contracts/extension/interface/IPlatformFee_V1.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

/// @author thirdweb

/**
* Thirdweb's `PlatformFee` is a contract extension to be used with any base contract. It exposes functions for setting and reading
* the recipient of platform fee and the platform fee basis points, and lets the inheriting contract perform conditional logic
* that uses information about platform fees, if desired.
*/

interface IPlatformFee {
/// @dev Fee type variants: percentage fee and flat fee
enum PlatformFeeType {
Bps,
Flat
}

/// @dev Returns the platform fee bps and recipient.
function getPlatformFeeInfo() external view returns (address, uint16);

/// @dev Lets a module admin update the fees on primary sales.
function setPlatformFeeInfo(address _platformFeeRecipient, uint256 _platformFeeBps) external;

/// @dev Emitted when fee on primary sales is updated.
event PlatformFeeInfoUpdated(address indexed platformFeeRecipient, uint256 platformFeeBps);

/// @dev Emitted when the flat platform fee is updated.
event FlatPlatformFeeUpdated(address platformFeeRecipient, uint256 flatFee);

/// @dev Emitted when the platform fee type is updated.
event PlatformFeeTypeUpdated(PlatformFeeType feeType);
}
21 changes: 21 additions & 0 deletions contracts/legacy-contracts/extension/interface/IPrimarySale_V1.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

/// @author thirdweb

/**
* Thirdweb's `Primary` is a contract extension to be used with any base contract. It exposes functions for setting and reading
* the recipient of primary sales, and lets the inheriting contract perform conditional logic that uses information about
* primary sales, if desired.
*/

interface IPrimarySale {
/// @dev The adress that receives all primary sales value.
function primarySaleRecipient() external view returns (address);

/// @dev Lets a module admin set the default recipient of all primary sales.
function setPrimarySaleRecipient(address _saleRecipient) external;

/// @dev Emitted when a new sale recipient is set.
event PrimarySaleRecipientUpdated(address indexed recipient);
}
21 changes: 17 additions & 4 deletions contracts/prebuilts/account/utils/AccountCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,17 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
return entrypointContract;
}

/// @notice Returns whether a signer is authorized to perform transactions using the wallet.
/**
@notice Returns whether a signer is authorized to perform transactions using the account.
Validity of the signature is based upon signer permission start/end timestamps, txn target, and txn value.
Account admins will always return true, and signers with address(0) as the only approved target will skip target checks.
@param _signer The signer to check.
@param _userOp The user operation to check.
@return Whether the signer is authorized to perform the transaction.
*/

/* solhint-disable*/
function isValidSigner(address _signer, UserOperation calldata _userOp) public view virtual returns (bool) {
// First, check if the signer is an admin.
Expand All @@ -102,6 +112,7 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
// if address(0) is the only approved target, set isWildCard to true (wildcard approved).
bool isWildCard = approvedTargets.length() == 1 && approvedTargets.at(0) == address(0);

// checking target and value for `execute`
if (sig == AccountExtension.execute.selector) {
// Extract the `target` and `value` arguments from the calldata for `execute`.
(address target, uint256 value) = decodeExecuteCalldata(_userOp.callData);
Expand All @@ -115,12 +126,14 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
}
}

// Check if the value is within the allowed range and if the target is approved.
// Check if the value is within the allowed range.
if (permissions.nativeTokenLimitPerTransaction < value) {
// Account: value too high OR Account: target not approved.
return false;
}
} else if (sig == AccountExtension.executeBatch.selector) {
}
// checking target and value for `executeBatch`
else if (sig == AccountExtension.executeBatch.selector) {
// Extract the `target` and `value` array arguments from the calldata for `executeBatch`.
(address[] memory targets, uint256[] memory values, ) = decodeExecuteBatchCalldata(_userOp.callData);

Expand All @@ -134,7 +147,7 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
}
}

// For each target+value pair, check if the value is within the allowed range and if the target is approved.
// For each target+value pair, check if the value is within the allowed range.
for (uint256 i = 0; i < targets.length; i++) {
if (permissions.nativeTokenLimitPerTransaction < values[i]) {
// Account: value too high OR Account: target not approved.
Expand Down
Loading

0 comments on commit 793c67b

Please sign in to comment.