2023-08-04 00:39:48 -07:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
pragma solidity ^0.8.19;
|
|
|
|
|
|
|
|
import { IENSResolver } from "@interfaces/IENSResolver.sol";
|
2023-08-04 08:00:05 -07:00
|
|
|
import { ISablier, SablierStream } from "@interfaces/ISablier.sol";
|
2023-08-04 00:39:48 -07:00
|
|
|
import { ProposalUtils } from "./utils/ProposalUtils.sol";
|
|
|
|
import { RemunerationProposal } from "@root/RemunerationProposal.sol";
|
|
|
|
|
|
|
|
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
|
import { console2 } from "@forge-std/console2.sol";
|
2023-08-04 08:00:05 -07:00
|
|
|
import { Vm } from "@forge-std/Vm.sol";
|
2023-08-04 00:39:48 -07:00
|
|
|
|
|
|
|
contract TestRemunerationProposal is ProposalUtils {
|
|
|
|
modifier executeCurrentProposalBefore() {
|
|
|
|
createAndExecuteProposal();
|
|
|
|
_;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createAndExecuteProposal() public {
|
|
|
|
address proposalAddress = address(new RemunerationProposal());
|
|
|
|
|
|
|
|
proposeAndExecute(proposalAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
function computeNamehash(string memory name) public pure returns (bytes32 namehash) {
|
|
|
|
namehash = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
namehash = keccak256(abi.encodePacked(namehash, keccak256(abi.encodePacked("eth"))));
|
|
|
|
namehash = keccak256(abi.encodePacked(namehash, keccak256(abi.encodePacked(name))));
|
|
|
|
}
|
|
|
|
|
|
|
|
function resolveDeveloperAddress() internal view returns (address) {
|
|
|
|
address ensResolverAddress = 0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63;
|
|
|
|
string memory developerENSName = "tornado-dev";
|
|
|
|
bytes32 developerENSNode = computeNamehash(developerENSName);
|
|
|
|
|
|
|
|
return IENSResolver(ensResolverAddress).addr(developerENSNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
function testDeveloperAddressIsCorrect() public view {
|
|
|
|
address developerAddressInProposal = 0x9Ff3C1Bea9ffB56a78824FE29f457F066257DD58;
|
|
|
|
address resolvedDeveloperAddress = resolveDeveloperAddress();
|
|
|
|
|
|
|
|
console2.log("Developer address in proposal: %s", developerAddressInProposal);
|
|
|
|
console2.log("Resolved developer address via ENS: %s", resolvedDeveloperAddress);
|
|
|
|
|
|
|
|
require(developerAddressInProposal == resolvedDeveloperAddress, "Developer remuneration address in proposal is incorrect");
|
|
|
|
}
|
|
|
|
|
|
|
|
function testDeveloperReceivedFunds() public {
|
|
|
|
IERC20 TORN = IERC20(tornTokenAddress);
|
|
|
|
address developerAddress = resolveDeveloperAddress();
|
2023-08-04 00:47:06 -07:00
|
|
|
uint256 reimbursementAmount = 1725 ether;
|
|
|
|
uint256 bountyAmount = 575 ether;
|
2023-08-04 00:39:48 -07:00
|
|
|
|
|
|
|
uint256 developerBalanceBeforeProposalExecution = TORN.balanceOf(developerAddress);
|
|
|
|
console2.log("Developer TORN balance before proposal execution: %s", developerBalanceBeforeProposalExecution / 1e18);
|
|
|
|
|
|
|
|
createAndExecuteProposal();
|
|
|
|
|
|
|
|
uint256 developerBalanceAfterProposalExecution = TORN.balanceOf(developerAddress);
|
|
|
|
console2.log("Developer TORN balance after proposal execution: %s", developerBalanceAfterProposalExecution / 1e18);
|
|
|
|
|
|
|
|
require(
|
|
|
|
developerBalanceBeforeProposalExecution + reimbursementAmount + bountyAmount == developerBalanceAfterProposalExecution,
|
|
|
|
"Developer didn't get reimbursement"
|
|
|
|
);
|
|
|
|
}
|
2023-08-04 08:00:05 -07:00
|
|
|
|
|
|
|
function testSablierStreamOpenedCorrectly() public {
|
|
|
|
uint256 remunerationAmountInTORN = 8625 ether;
|
|
|
|
address sablierAddress = 0xCD18eAa163733Da39c232722cBC4E8940b1D8888;
|
|
|
|
|
|
|
|
vm.recordLogs();
|
|
|
|
createAndExecuteProposal();
|
|
|
|
Vm.Log[] memory logs = vm.getRecordedLogs();
|
|
|
|
|
|
|
|
Vm.Log memory sablierCreateStreamLog;
|
|
|
|
|
|
|
|
for (uint16 i = 0; i < logs.length; i++) {
|
|
|
|
if (logs[i].emitter == sablierAddress) sablierCreateStreamLog = logs[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
uint256 sablierStreamId = uint256(sablierCreateStreamLog.topics[1]);
|
|
|
|
|
|
|
|
SablierStream memory openedStream = ISablier(sablierAddress).getStream(sablierStreamId);
|
|
|
|
|
|
|
|
require(openedStream.deposit + 1 ether > remunerationAmountInTORN, "Developer remuneration stream amount is insufficient");
|
|
|
|
require(openedStream.deposit == openedStream.remainingBalance, "Stream started incorrectly");
|
|
|
|
require(openedStream.stopTime < block.timestamp + 91 days, "Stream duration is more than quarter");
|
|
|
|
require(openedStream.recipient == resolveDeveloperAddress(), "Stream recipient isn't developer");
|
|
|
|
}
|
2023-08-04 00:39:48 -07:00
|
|
|
}
|