文件 1 的 1:ChonkStripper.sol
pragma solidity ^0.8.26;
interface ChonksMain {
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function getTBAAddressForChonkId(uint256 _chonkId) external view returns (address);
function traitsContract() external view returns (address);
function unequipAll(uint256 _chonkTokenId) external;
function getChonkIdForTBAAddress(address _tbaAddress) external view returns (uint256);
}
interface ChonkTraits {
function transferFrom(address from, address to, uint256 tokenId) external;
function walletOfOwner(address _owner) external view returns(uint256[] memory);
}
interface ChonkTba {
function execute(address to, uint256 value, bytes calldata data, uint8 operation) external payable returns (bytes memory);
}
interface WrappedChonks {
function transfer(address recipient, uint256 amount) external;
}
contract ChonkStripper {
address constant private _chonksMain = 0x07152bfde079b5319e5308C43fB1Dbc9C76cb4F9;
bytes4 constant private _tbaTransferSelector = bytes4(keccak256("transferFrom(address,address,uint256)"));
address constant private _wrapped = 0x172ab1C8278Fc267D959682534f319609B6Dc258;
uint256 constant private _oneToken = 10**18;
mapping(address => address) private _closets;
mapping(address => bool) private _wrap;
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
function setMyCloset(uint256 chonkId) external {
ChonksMain main = ChonksMain(_chonksMain);
address tbaAddress = main.getTBAAddressForChonkId(chonkId);
require(tbaAddress != address(0), "Chonk ID Invalid");
_closets[msg.sender] = tbaAddress;
}
function setMyWrapAfterStrip(bool wrap) external {
_wrap[msg.sender] = wrap;
}
function getOwnerCloset(address _owner) public view returns (address){
address closet = _closets[_owner];
require(closet != address(0), "Owner has no closet");
return closet;
}
function isOwnerWrapAfterStrip(address _owner) public view returns (bool){
return _wrap[_owner];
}
function onERC721Received(address _address, address from, uint256 tokenId, bytes calldata _data) external returns (bytes4) {
if (msg.sender != _chonksMain) {
revert();
}
ChonksMain main = ChonksMain(_chonksMain);
address traitsAddress = main.traitsContract();
ChonkTraits traits = ChonkTraits(traitsAddress);
address tbaAddress = main.getTBAAddressForChonkId(tokenId);
ChonkTba tba = ChonkTba(tbaAddress);
address closet = getOwnerCloset(from);
uint256[] memory traitIds = traits.walletOfOwner(tbaAddress);
if (traitIds.length > 0){
main.unequipAll(tokenId);
}
for (uint256 n; n < traitIds.length; ++n) {
uint256 traitId = traitIds[n];
tba.execute(traitsAddress, 0, abi.encodeWithSelector(_tbaTransferSelector, tbaAddress, closet, traitId), 0);
}
if(isOwnerWrapAfterStrip(from)){
WrappedChonks token = WrappedChonks(_wrapped);
main.safeTransferFrom(address(this), _wrapped, tokenId);
token.transfer(from, _oneToken);
}else{
main.transferFrom(address(this), from, tokenId);
}
return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
}
function execute(address target, bytes calldata data) external onlyOwner returns (bool success, bytes memory result) {
require(target != address(0), "Target address cannot be zero");
(success, result) = target.call(data);
require(success, "Call failed");
}
}
{
"compilationTarget": {
"ChonkStripper.sol": "ChonkStripper"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}