forked from mico/idle_moloch
177 lines
4.5 KiB
Solidity
177 lines
4.5 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.7;
|
|
import "../Baal.sol";
|
|
|
|
interface IERC20 {
|
|
function transferFrom(
|
|
address from,
|
|
address to,
|
|
uint256 value
|
|
) external returns (bool);
|
|
}
|
|
|
|
contract TributeMinion {
|
|
event TributeProposal(
|
|
address indexed baal,
|
|
address token,
|
|
uint256 amount,
|
|
address recipient,
|
|
uint256 proposalId
|
|
);
|
|
struct Escrow {
|
|
address token;
|
|
address applicant;
|
|
uint256 amount;
|
|
bool released;
|
|
address safe;
|
|
}
|
|
mapping(address => mapping(uint256 => Escrow)) public escrows;
|
|
|
|
event EscrowReleased(
|
|
address indexed baal,
|
|
uint32 proposalId,
|
|
address applicant,
|
|
address safe,
|
|
uint256 amount
|
|
);
|
|
|
|
function encodeTributeProposal(
|
|
address baal,
|
|
uint256 shares,
|
|
uint256 loot,
|
|
address recipient,
|
|
uint32 proposalId,
|
|
address escrow
|
|
) public pure returns (bytes memory) {
|
|
// Workaround for solidity dynamic memory array
|
|
address[] memory _recipients = new address[](1);
|
|
_recipients[0] = recipient;
|
|
|
|
bytes memory _releaseEscrow = abi.encodeWithSignature(
|
|
"releaseEscrow(address,uint32)",
|
|
baal,
|
|
proposalId
|
|
);
|
|
|
|
bytes memory tributeMultisend = abi.encodePacked(
|
|
uint8(0),
|
|
escrow,
|
|
uint256(0),
|
|
uint256(_releaseEscrow.length),
|
|
bytes(_releaseEscrow)
|
|
);
|
|
|
|
if (shares > 0) {
|
|
// Workaround for solidity dynamic memory array
|
|
uint256[] memory _shares = new uint256[](1);
|
|
_shares[0] = shares;
|
|
|
|
bytes memory _issueShares = abi.encodeWithSignature(
|
|
"mintShares(address[],uint256[])",
|
|
_recipients,
|
|
_shares
|
|
);
|
|
|
|
tributeMultisend = abi.encodePacked(
|
|
tributeMultisend,
|
|
uint8(0),
|
|
baal,
|
|
uint256(0),
|
|
uint256(_issueShares.length),
|
|
bytes(_issueShares)
|
|
);
|
|
}
|
|
if (loot > 0) {
|
|
// Workaround for solidity dynamic memory array
|
|
uint256[] memory _loot = new uint256[](1);
|
|
_loot[0] = loot;
|
|
|
|
bytes memory _issueLoot = abi.encodeWithSignature(
|
|
"mintLoot(address[],uint256[])",
|
|
_recipients,
|
|
_loot
|
|
);
|
|
|
|
tributeMultisend = abi.encodePacked(
|
|
tributeMultisend,
|
|
uint8(0),
|
|
address(baal),
|
|
uint256(0),
|
|
uint256(_issueLoot.length),
|
|
bytes(_issueLoot)
|
|
);
|
|
}
|
|
|
|
bytes memory _multisendAction = abi.encodeWithSignature(
|
|
"multiSend(bytes)",
|
|
tributeMultisend
|
|
);
|
|
return _multisendAction;
|
|
}
|
|
|
|
function submitTributeProposal(
|
|
Baal baal,
|
|
address token,
|
|
uint256 amount,
|
|
uint256 shares,
|
|
uint256 loot,
|
|
uint32 expiration,
|
|
uint256 baalgas,
|
|
string memory details
|
|
) external payable {
|
|
uint32 proposalId = baal.proposalCount() + 1;
|
|
|
|
bytes memory encodedProposal = encodeTributeProposal(
|
|
address(baal),
|
|
shares,
|
|
loot,
|
|
msg.sender,
|
|
proposalId,
|
|
address(this)
|
|
);
|
|
|
|
escrows[address(baal)][proposalId] = Escrow(
|
|
token,
|
|
msg.sender,
|
|
amount,
|
|
false,
|
|
baal.target()
|
|
);
|
|
|
|
baal.submitProposal{value:msg.value}(encodedProposal, expiration, baalgas, details);
|
|
|
|
emit TributeProposal(
|
|
address(baal),
|
|
token,
|
|
amount,
|
|
msg.sender,
|
|
proposalId
|
|
);
|
|
}
|
|
|
|
function releaseEscrow(address _baal, uint32 _proposalId) external {
|
|
Baal baal = Baal(_baal);
|
|
Escrow storage escrow = escrows[address(baal)][_proposalId];
|
|
require(!escrow.released, "Already released");
|
|
|
|
bool[4] memory status = baal.getProposalStatus(_proposalId);
|
|
require(status[2], "Not passed");
|
|
escrow.released = true;
|
|
|
|
IERC20 token = IERC20(escrow.token);
|
|
|
|
emit EscrowReleased(
|
|
_baal,
|
|
_proposalId,
|
|
escrow.applicant,
|
|
escrow.safe,
|
|
escrow.amount
|
|
);
|
|
|
|
require(
|
|
token.transferFrom(escrow.applicant, escrow.safe, escrow.amount),
|
|
"Transfer failed"
|
|
);
|
|
}
|
|
}
|