DelegateTokenTransferHelpers::checkERC1155BeforePull() and DelegateTokenTransferHelpers::pullERC1155AfterCheck() perform βset and checkβ operations on erc1155Pulled.flag which will always revert. In the first function, the value of erc1155Pulled.flag is set to ERC1155_PULLED, and in the second function, it reverts if the value of erc1155Pulled.flag is set to ERC1155_PULLED.
Code snippet from DelegateTokenTransferHelpers::checkERC1155BeforePull():
if (erc1155Pulled.flag == ERC1155_NOT_PULLED) {
erc1155Pulled.flag = ERC1155_PULLED;
}
Code snippet from DelegateTokenTransferHelpers::pullERC1155AfterCheck():
if (erc1155Pulled.flag == ERC1155_PULLED) {
revert Errors.ERC1155NotPulled();
}
The DelegateTokenTransferHelpers::checkAndPullByType() function calls the above two methods back to back, and hence the DelegateTokenTransferHelpers::checkAndPullByType() function call for ERC1155 is bound to revert every time.
DelegateTokenTransferHelpers::checkAndPullByType() is called from the DelegateToken::create() function. The DelegateToken::create() is the function where new Delegation and Principal tokens are created for the different kind of tokens. Because DelegateTokenTransferHelpers::checkAndPullByType() will revert, it will cause DelegateToken::create() to revert as well for ERC1155, thereby making the protocol not work for ERC1155.
Below is a proof of concept that can be run on Remix directly. The proof of concept below is the minimal setup extracted from the actual codebase to simulate the issue.
pragma solidity ^0.8.21;
contract TestContract {
Structs.Uint256 internal erc1155PullAuthorization = Structs.Uint256(DelegateTokenTransferHelpers.ERC1155_NOT_PULLED);
function runTest() external {
DelegateTokenTransferHelpers.checkAndPullByType(
erc1155PullAuthorization
);
}
}
library Structs {
struct Uint256 {
uint256 flag;
}
}
library DelegateTokenTransferHelpers {
uint256 internal constant ERC1155_NOT_PULLED = 5;
uint256 internal constant ERC1155_PULLED = 6;
error ERC1155NotPulled();
function checkAndPullByType(
Structs.Uint256 storage erc1155Pulled
) external {
checkERC1155BeforePull(erc1155Pulled);
pullERC1155AfterCheck(
erc1155Pulled
);
}
function checkERC1155BeforePull(
Structs.Uint256 storage erc1155Pulled
) internal {
if (erc1155Pulled.flag == ERC1155_NOT_PULLED) {
erc1155Pulled.flag = ERC1155_PULLED;
}
}
function pullERC1155AfterCheck(
Structs.Uint256 storage erc1155Pulled
) internal {
if (erc1155Pulled.flag == ERC1155_PULLED) {
revert ERC1155NotPulled();
}
}
}
Manual analysis
Update the the functions DelegateTokenTransferHelpers::checkERC1155BeforePull() and DelegateTokenTransferHelpers::pullERC1155AfterCheck() so that the first function doesnβt set values which make the second function revert.
Other
The text was updated successfully, but these errors were encountered:
All reactions