Skip to content

Problem: missing internal tx when debug trace tx #575

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

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
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
82 changes: 82 additions & 0 deletions tests/integration_tests/expected_constants.py

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions tests/integration_tests/hardhat/contracts/BonusDistributor.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./BonusMultiplier.sol";

contract BonusDistributor {
using SafeERC20 for ERC20;

ERC20 public bonusToken;
address public bonusMultiplier;

constructor(address _bonusToken) {
bonusToken = ERC20(_bonusToken);
}

function setBonusMultiplier(address _bonusMultiplier) public {
bonusMultiplier = _bonusMultiplier;
}

function distributeBonusWithEther(address recipient, uint256 amount, uint256 etherValue) public {
require(address(this).balance >= etherValue, "Insufficient Ether in distributor");
uint256 bonusAmount = amount / 10;

if (bonusMultiplier != address(0)) {
payable(bonusMultiplier).transfer(etherValue);
BonusMultiplier(payable(bonusMultiplier)).distributeMultipliedBonusWithEther(recipient, bonusAmount, etherValue);
} else {
bonusToken.safeTransfer(recipient, bonusAmount);
}
}

receive() external payable {}
}
29 changes: 29 additions & 0 deletions tests/integration_tests/hardhat/contracts/BonusMultiplier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract BonusMultiplier {
using SafeERC20 for ERC20;

ERC20 public bonusToken;
uint256 public multiplier;

constructor(address _bonusToken) {
bonusToken = ERC20(_bonusToken);
multiplier = 2;
}

function setMultiplier(uint256 _multiplier) public {
multiplier = _multiplier;
}

function distributeMultipliedBonusWithEther(address recipient, uint256 amount, uint256 etherValue) public {
require(address(this).balance >= etherValue, "Insufficient Ether in multiplier");
bonusToken.safeTransfer(recipient, amount * multiplier);
payable(recipient).transfer(etherValue);
}

receive() external payable {}
}
66 changes: 66 additions & 0 deletions tests/integration_tests/hardhat/contracts/TestPack.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { Pack } from "@thirdweb-dev/contracts/contracts/prebuilts/pack/Pack.sol";
import { ITokenBundle } from "@thirdweb-dev/contracts/contracts/extension/interface/ITokenBundle.sol";
import { Wallet } from "./utils/Wallet.sol";
import "./mocks/WETH9.sol";
import { Forwarder } from "@thirdweb-dev/contracts/contracts/infra/forwarder/Forwarder.sol";
import { TWRegistry } from "@thirdweb-dev/contracts/contracts/infra/TWRegistry.sol";
import { TWFactory } from "@thirdweb-dev/contracts/contracts/infra/TWFactory.sol";

contract TestPack is Wallet {
string public constant NAME = "NAME";
string public constant SYMBOL = "SYMBOL";
string public constant CONTRACT_URI = "CONTRACT_URI";
address public constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
string internal packUri = "ipfs://";

Pack internal pack;
Wallet internal tokenOwner;

event ProxyAddress(address indexed proxyAddress);

function setUp(
address _forwarder,
address _factory,
address _recipient
) public payable {
address deployer = address(this);
address royaltyRecipient = address(0x30001);
uint128 royaltyBps = 500; // 5%

address[] memory forwarders = new address[](1);
forwarders[0] = _forwarder;
string memory _contractType = "Pack";
bytes memory _initializer = abi.encodeCall(
Pack.initialize,
(deployer, NAME, SYMBOL, CONTRACT_URI, forwarders, royaltyRecipient, royaltyBps)
);
address proxyAddress = TWFactory(_factory).deployProxy(bytes32(bytes(_contractType)), _initializer);
emit ProxyAddress(proxyAddress);
pack = Pack(payable(proxyAddress));
tokenOwner = Wallet(address(this));

createPackWithNativeTokens(_recipient, 20 ether, 20);
createPackWithNativeTokens(_recipient, 2 ether, 2);
}

function createPackWithNativeTokens(address recipient, uint256 amount, uint256 numOfRewardUnit) internal {
ITokenBundle.Token[] memory packContents = new ITokenBundle.Token[](1);
packContents[0] = ITokenBundle.Token(NATIVE_TOKEN, ITokenBundle.TokenType.ERC20, 0, amount);

uint256[] memory numOfRewardUnits = new uint256[](1);
numOfRewardUnits[0] = numOfRewardUnit;

pack.createPack{ value: amount}(
packContents,
numOfRewardUnits,
packUri,
0,
1,
recipient
);
}
}
33 changes: 33 additions & 0 deletions tests/integration_tests/hardhat/contracts/TokenDistributor.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./BonusDistributor.sol";

contract TokenDistributor {
using SafeERC20 for ERC20;

ERC20 public token;
address public bonusDistributor;

constructor(address _token) {
token = ERC20(_token);
}

function setBonusDistributor(address _bonusDistributor) public {
bonusDistributor = _bonusDistributor;
}

function distributeTokens(address[] memory recipients, uint256[] memory amounts) public payable {
require(recipients.length == amounts.length, "Recipients and amounts arrays must be the same length");

for (uint256 i = 0; i < recipients.length; i++) {
token.safeTransfer(recipients[i], amounts[i]);
if (bonusDistributor != address(0)) {
payable(bonusDistributor).transfer(msg.value);
BonusDistributor(payable(bonusDistributor)).distributeBonusWithEther(recipients[i], amounts[i], msg.value);
}
}
}
}
27 changes: 27 additions & 0 deletions tests/integration_tests/hardhat/contracts/mocks/MockERC1155.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol";

contract MockERC1155 is ERC1155PresetMinterPauser {
constructor() ERC1155PresetMinterPauser("ipfs://BaseURI") {}

function mint(address to, uint256 id, uint256 amount) public virtual {
_mint(to, id, amount, "");
}

function hasRole(bytes32, address) public pure override(AccessControl, IAccessControl) returns (bool) {
return true;
}

function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint");

_mintBatch(to, ids, amounts, "");
}

function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId);
}
}
38 changes: 38 additions & 0 deletions tests/integration_tests/hardhat/contracts/mocks/MockERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

contract MockERC20 is ERC20PresetMinterPauser, ERC20Permit {
bool internal taxActive;

constructor() ERC20PresetMinterPauser("Mock Coin", "MOCK") ERC20Permit("Mock Coin") {}

function mint(address to, uint256 amount) public override(ERC20PresetMinterPauser) {
_mint(to, amount);
}

function toggleTax() external {
taxActive = !taxActive;
}

function _transfer(address from, address to, uint256 amount) internal override {
if (taxActive) {
uint256 tax = (amount * 10) / 100;
amount -= tax;
super._transfer(from, address(this), tax);
}
super._transfer(from, to, amount);
}

function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal override(ERC20PresetMinterPauser, ERC20) {
super._beforeTokenTransfer(from, to, amount);
}
}
25 changes: 25 additions & 0 deletions tests/integration_tests/hardhat/contracts/mocks/MockERC721.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";

contract MockERC721 is ERC721Burnable {
uint256 public nextTokenIdToMint;

constructor() ERC721("MockERC721", "MOCK") {}

function mint(address _receiver, uint256 _amount) external {
uint256 tokenId = nextTokenIdToMint;
nextTokenIdToMint += _amount;

for (uint256 i = 0; i < _amount; i += 1) {
_mint(_receiver, tokenId);
tokenId += 1;
}
}

function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId);
}
}
31 changes: 31 additions & 0 deletions tests/integration_tests/hardhat/contracts/mocks/WETH9.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.11;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract WETH9 is ERC20 {
event Deposit(address indexed sender, uint256 amount);
event Withdrawal(address indexed sender, uint256 amount);

constructor() ERC20("Wrapped Ether", "WETH") {}

receive() external payable virtual {
deposit();
}

function deposit() public payable {
_mint(msg.sender, msg.value);
emit Deposit(msg.sender, msg.value);
}

function withdraw(uint256 amount) public {
_burn(msg.sender, amount);
payable(msg.sender).transfer(amount);
emit Withdrawal(msg.sender, amount);
}

function totalSupply() public view override returns (uint256) {
return address(this).balance;
}
}
48 changes: 48 additions & 0 deletions tests/integration_tests/hardhat/contracts/utils/Wallet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.11;

import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";

import "../mocks/MockERC20.sol";
import "../mocks/MockERC721.sol";
import "../mocks/MockERC1155.sol";

contract Wallet is ERC721Holder, ERC1155Holder {
function transferERC20(address token, address to, uint256 amount) public {
MockERC20(token).transfer(to, amount);
}

function setAllowanceERC20(address token, address spender, uint256 allowanceAmount) public {
MockERC20(token).approve(spender, allowanceAmount);
}

function burnERC20(address token, uint256 amount) public {
MockERC20(token).burn(amount);
}

function transferERC721(address token, address to, uint256 tokenId) public {
MockERC721(token).transferFrom(address(this), to, tokenId);
}

function setApprovalForAllERC721(address token, address operator, bool toApprove) public {
MockERC721(token).setApprovalForAll(operator, toApprove);
}

function burnERC721(address token, uint256 tokenId) public {
MockERC721(token).burn(tokenId);
}

function transferERC1155(address token, address to, uint256 tokenId, uint256 amount, bytes calldata data) external {
MockERC1155(token).safeTransferFrom(address(this), to, tokenId, amount, data);
}

function setApprovalForAllERC1155(address token, address operator, bool toApprove) public {
MockERC1155(token).setApprovalForAll(operator, toApprove);
}

function burnERC1155(address token, uint256 tokenId, uint256 amount) public {
MockERC1155(token).burn(address(this), tokenId, amount);
}
}
Loading
Loading