{"workflow":null,"planning":null,"id":"2a1dcd8a-6ed3-4bb0-b285-161785217a8d","state":"completed","template":"shape:chain","objective":"Token name: Work\nToken symbol: WORK\nWrite these 4 files EXACTLY as given (already tested; formatting only, never change logic). foundry.toml: solc 0.8.26, evm_version cancun, optimizer true, optimizer_runs 200, via_ir true, bytecode_hash \"none\"; vendor Uniswap v4-core v4.0.0 at lib/v4-core and OpenZeppelin v5 at lib/openzeppelin-contracts, remappings v4-core/=lib/v4-core/ and @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/. Hook is deployed at a CREATE2 address with flags 0x20C4; the third constructor arg is the already-deployed WORKERS NFT (exposes tradingOpenAt()). Fees: every hook fee (snipe 50% sliding to 2% over 15 min after the WORKERS NFT's tradingOpenAt, then 2%) goes to the treasury 0xc9eafe33a510a3a3d95a94c4f85adaf6a3ea12a0 via a permissionless sweep. Admin: that same address may only set the standing fee within 0-10%; no other admin, no upgrades. Tests against the real PoolManager.\nlaunch.json:\n{\"kind\":\"univ4_hook\",\"hook\":{\"contract\":\"WorkGateHook\",\"constructorArgs\":[\"$poolManager\",\"$token\",\"0x363860179149628b6fd73b7e05a6cd102de3a72a\"],\"permissions\":[\"beforeInitialize\",\"beforeSwap\",\"afterSwap\",\"afterSwapReturnDelta\"]},\"token\":{\"contract\":\"Work\",\"name\":\"Work\",\"symbol\":\"WORK\",\"decimals\":18},\"pool\":{\"pairedCurrency\":\"0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127\",\"fee\":12500,\"tickSpacing\":60,\"initialPrice\":\"79228162514264337593543950336\"}}\nsrc/Work.sol:\npragma solidity 0.8.26;import{ERC20}from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";contract Work is ERC20{constructor()ERC20(\"Work\",\"WORK\"){_mint(msg.sender,1_000_000_000 ether);}}\nsrc/WorkGateHook.sol:\n// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;import{IPoolManager}from \"v4-core/src/interfaces/IPoolManager.sol\";import{IHooks}from \"v4-core/src/interfaces/IHooks.sol\";import{Hooks}from \"v4-core/src/libraries/Hooks.sol\";import{PoolKey}from \"v4-core/src/types/PoolKey.sol\";import{Currency}from \"v4-core/src/types/Currency.sol\";import{BalanceDelta}from \"v4-core/src/types/BalanceDelta.sol\";import{BeforeSwapDelta}from \"v4-core/src/types/BeforeSwapDelta.sol\";contract WorkGateHook{address public constant IMD=0x5F7Bb59365ce557C26dbcAa4EE9d39A4b95B7127;address public constant B=0xc9EAFE33A510a3a3d95A94c4f85AdaF6a3EA12a0;IPoolManager public immutable poolManager;address public immutable token;address public immutable workers;uint256 public openedAt;uint256 public standingFee=200;bool public initialized;error TradingClosed();event StandingFee(uint256 fee);constructor(IPoolManager m,address t,address w){require(t!=IMD&&w.code.length>0);poolManager=m;token=t;workers=w;Hooks.validateHookPermissions(IHooks(address(this)),Hooks.Permissions(true,false,false,false,false,false,true,true,false,false,false,true,false,false));}modifier onlyPM(){require(msg.sender==address(poolManager));_;}function beforeInitialize(address,PoolKey calldata k,uint160)external onlyPM returns(bytes4){address a=Currency.unwrap(k.currency0);address b=Currency.unwrap(k.currency1);require(!initialized&&((a==IMD&&b==token)||(a==token&&b==IMD))&&k.fee==12500&&k.tickSpacing==60&&address(k.hooks)==address(this));initialized=true;return IHooks.beforeInitialize.selector;}function tradingOpenAt()public view returns(uint256 t){t=openedAt;if(t==0){(bool ok,bytes memory r)=workers.staticcall{gas:50000}(abi.encodeWithSignature(\"tradingOpenAt()\"));if(ok&&r.length>31)t=abi.decode(r,(uint256));if(t>block.timestamp)t=0;}}function tradingOpen()external view returns(bool){return tradingOpenAt()!=0;}function feeNow()public view returns(uint256){uint256 t=tradingOpenAt();uint256 s=standingFee;if(t==0||block.timestamp<=t)return 5000;t=block.timestamp-t;return t<900?s+(5000-s)*(900-t)/900:s;}function setStandingFee(uint256 f)external{require(msg.sender==B&&f<=1000);standingFee=f;emit StandingFee(f);}function beforeSwap(address,PoolKey calldata,IPoolManager.SwapParams calldata,bytes calldata)external onlyPM returns(bytes4,BeforeSwapDelta,uint24){if(openedAt==0){uint256 t=tradingOpenAt();if(t==0)revert TradingClosed();openedAt=t;}return(IHooks.beforeSwap.selector,BeforeSwapDelta.wrap(0),0);}function afterSwap(address,PoolKey calldata k,IPoolManager.SwapParams calldata p,BalanceDelta d,bytes calldata)external onlyPM returns(bytes4,int128){bool u1=(p.amountSpecified<0)==p.zeroForOne;int128 a=u1?d.amount1():d.amount0();uint256 f=uint256(int256(a<0?-a:a))*feeNow()/10000;if(f>0)poolManager.mint(address(this),(u1?k.currency1:k.currency0).toId(),f);return(IHooks.afterSwap.selector,int128(int256(f)));}function sweep()external{poolManager.unlock(\"\");address[3]memory c=[IMD,token,address(0)];for(uint256 i;i<3;++i){Currency x=Currency.wrap(c[i]);uint256 v=x.balanceOfSelf();if(v>0)x.transfer(B,v);}}function unlockCallback(bytes calldata)external onlyPM returns(bytes memory){for(uint256 i;i<2;++i){Currency x=Currency.wrap(i==0?IMD:token);uint256 v=poolManager.balanceOf(address(this),x.toId());if(v>0){poolManager.burn(address(this),x.toId(),v);poolManager.take(x,B,v);}}return \"\";}}\n","blockedReason":null,"createdAt":"2026-10-07T23:05:28.768Z","updatedAt":"2026-10-07T23:39:31.428Z","paidBy":"0xc9eafe33a510a3a3d95a94c4f85adaf6a3ea12a0","parentJobId":null,"project":{"id":"2a1dcd8a-6ed3-4bb0-b285-161785217a8d","head":"2a1dcd8a-6ed3-4bb0-b285-161785217a8d","running":null,"versions":[{"jobId":"2a1dcd8a-6ed3-4bb0-b285-161785217a8d","workflowId":null,"objective":"Token name: Work\nToken symbol: WORK\nWrite these 4 files EXACTLY as given (already tested; formatting only, never change logic). foundry.toml: solc 0.8.26, evm_version cancun, optimizer true, optimizer_runs 200, via_ir true, bytecode_hash \"none\"; vendor Uniswap v4-core v4.0.0 at lib/v4-core and OpenZeppelin v5 at lib/openzeppelin-contracts, remappings v4-core/=lib/v4-core/ and @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/. Hook is deployed at a CREATE2 address with flags 0x20C4; the third constructor arg is the already-deployed WORKERS NFT (exposes tradingOpenAt()). Fees: every hook fee (snipe 50% sliding to 2% over 15 min after the WORKERS NFT's tradingOpenAt, then 2%) goes to the treasury 0xc9eafe33a510a3a3d95a94c4f85adaf6a3ea12a0 via a permissionless sweep. Admin: that same address may only set the standing fee within 0-10%; no other admin, no upgrades. Tests against the real PoolManager.\nlaunch.json:\n{\"kind\":\"univ4_hook\",\"hook\":{\"contract\":\"WorkGateHook\",\"constructorArgs\":[\"$poolManager\",\"$token\",\"0x363860179149628b6fd73b7e05a6cd102de3a72a\"],\"permissions\":[\"beforeInitialize\",\"beforeSwap\",\"afterSwap\",\"afterSwapReturnDelta\"]},\"token\":{\"contract\":\"Work\",\"name\":\"Work\",\"symbol\":\"WORK\",\"decimals\":18},\"pool\":{\"pairedCurrency\":\"0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127\",\"fee\":12500,\"tickSpacing\":60,\"initialPrice\":\"79228162514264337593543950336\"}}\nsrc/Work.sol:\npragma solidity 0.8.26;import{ERC20}from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";contract Work is ERC20{constructor()ERC20(\"Work\",\"WORK\"){_mint(msg.sender,1_000_000_000 ether);}}\nsrc/WorkGateHook.sol:\n// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;import{IPoolManager}from \"v4-core/src/interfaces/IPoolManager.sol\";import{IHooks}from \"v4-core/src/interfaces/IHooks.sol\";import{Hooks}from \"v4-core/src/libraries/Hooks.sol\";import{PoolKey}from \"v4-core/src/types/PoolKey.sol\";import{Currency}from \"v4-core/src/types/Currency.sol\";import{BalanceDelta}from \"v4-core/src/types/BalanceDelta.sol\";import{BeforeSwapDelta}from \"v4-core/src/types/BeforeSwapDelta.sol\";contract WorkGateHook{address public constant IMD=0x5F7Bb59365ce557C26dbcAa4EE9d39A4b95B7127;address public constant B=0xc9EAFE33A510a3a3d95A94c4f85AdaF6a3EA12a0;IPoolManager public immutable poolManager;address public immutable token;address public immutable workers;uint256 public openedAt;uint256 public standingFee=200;bool public initialized;error TradingClosed();event StandingFee(uint256 fee);constructor(IPoolManager m,address t,address w){require(t!=IMD&&w.code.length>0);poolManager=m;token=t;workers=w;Hooks.validateHookPermissions(IHooks(address(this)),Hooks.Permissions(true,false,false,false,false,false,true,true,false,false,false,true,false,false));}modifier onlyPM(){require(msg.sender==address(poolManager));_;}function beforeInitialize(address,PoolKey calldata k,uint160)external onlyPM returns(bytes4){address a=Currency.unwrap(k.currency0);address b=Currency.unwrap(k.currency1);require(!initialized&&((a==IMD&&b==token)||(a==token&&b==IMD))&&k.fee==12500&&k.tickSpacing==60&&address(k.hooks)==address(this));initialized=true;return IHooks.beforeInitialize.selector;}function tradingOpenAt()public view returns(uint256 t){t=openedAt;if(t==0){(bool ok,bytes memory r)=workers.staticcall{gas:50000}(abi.encodeWithSignature(\"tradingOpenAt()\"));if(ok&&r.length>31)t=abi.decode(r,(uint256));if(t>block.timestamp)t=0;}}function tradingOpen()external view returns(bool){return tradingOpenAt()!=0;}function feeNow()public view returns(uint256){uint256 t=tradingOpenAt();uint256 s=standingFee;if(t==0||block.timestamp<=t)return 5000;t=block.timestamp-t;return t<900?s+(5000-s)*(900-t)/900:s;}function setStandingFee(uint256 f)external{require(msg.sender==B&&f<=1000);standingFee=f;emit StandingFee(f);}function beforeSwap(address,PoolKey calldata,IPoolManager.SwapParams calldata,bytes calldata)external onlyPM returns(bytes4,BeforeSwapDelta,uint24){if(openedAt==0){uint256 t=tradingOpenAt();if(t==0)revert TradingClosed();openedAt=t;}return(IHooks.beforeSwap.selector,BeforeSwapDelta.wrap(0),0);}function afterSwap(address,PoolKey calldata k,IPoolManager.SwapParams calldata p,BalanceDelta d,bytes calldata)external onlyPM returns(bytes4,int128){bool u1=(p.amountSpecified<0)==p.zeroForOne;int128 a=u1?d.amount1():d.amount0();uint256 f=uint256(int256(a<0?-a:a))*feeNow()/10000;if(f>0)poolManager.mint(address(this),(u1?k.currency1:k.currency0).toId(),f);return(IHooks.afterSwap.selector,int128(int256(f)));}function sweep()external{poolManager.unlock(\"\");address[3]memory c=[IMD,token,address(0)];for(uint256 i;i<3;++i){Currency x=Currency.wrap(c[i]);uint256 v=x.balanceOfSelf();if(v>0)x.transfer(B,v);}}function unlockCallback(bytes calldata)external onlyPM returns(bytes memory){for(uint256 i;i<2;++i){Currency x=Currency.wrap(i==0?IMD:token);uint256 v=poolManager.balanceOf(address(this),x.toId());if(v>0){poolManager.burn(address(this),x.toId(),v);poolManager.take(x,B,v);}}return \"\";}}\n","baseCommit":"0243d7da4a4337ae8b16bcdf15bb4ead736fd68f","state":"completed","createdAt":"2026-10-07T23:05:28.768Z"}]},"deliver":true,"host":false,"site":null,"launch":{"requested":true,"kind":"univ4_hook","id":"70c33665-65ef-47d5-96a8-368290250aac","status":"parked","chainId":4663},"oracleRequestId":null,"delivery":{"repoUrl":"https://github.com/identity-md-launches/launch-956-src-work-sol-src-workgatehook-sol","pullRequestUrl":"https://github.com/identity-md-launches/launch-956-src-work-sol-src-workgatehook-sol/pull/1","commit":"1a75c4f95e4f9e1d45734e211bfc6d1092e78e4b","deliveredAt":"2026-10-07T23:39:40.019Z","media":null},"media":null,"nodes":[{"key":"build_contract_project","role":"implement","state":"accepted","attempt":2,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-07T23:25:00.343Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+e892633c","verifiedTreeHash":"b0be27067524e15664a186b100784962a8b849a6","at":"2026-10-07T23:25:00.342Z","failedChecks":[]},"seat":{"tokenId":"209","agentId":"51007"},"live":null},{"key":"manifest","role":"integrate","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project","write_foundry_tests"],"allowedPaths":["launch.json"],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-07T23:39:31.428Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ef8fb83e","verifiedTreeHash":"cbe5cfa7f4dfe619dff766157d123799c59f578b","at":"2026-10-07T23:39:31.711Z","failedChecks":[]},"seat":{"tokenId":"22","agentId":"52391"},"live":null},{"key":"write_foundry_tests","role":"tests","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":["test","test/**"],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-07T23:35:55.849Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ef8fb83e","verifiedTreeHash":"cf3d2b17e45498159414c0d2dfe07fefed5221de","at":"2026-10-07T23:35:55.849Z","failedChecks":[]},"seat":{"tokenId":"488","agentId":"51523"},"live":null}],"reviews":[{"status":"queued","chainId":1,"txHash":null,"blockNumber":null,"sentAt":null,"entries":[{"nodeKey":"build_contract_project","agentId":"51095","value":0,"role":"verification:checks"},{"nodeKey":"build_contract_project","agentId":"51007","value":1,"role":"verification:checks"},{"nodeKey":"manifest","agentId":"52391","value":1,"role":"verification:checks"},{"nodeKey":"write_foundry_tests","agentId":"51523","value":1,"role":"verification:checks"}]}]}