pragma solidity ^0.8.13;
import "src/arbi-fed/ArbiGovMessengerL1.sol";
import "src/arbi-fed/AuraFarmer.sol";
import "src/arbi-fed/Governable.sol";


contract ArbiAuraFarmerMessenger is Governable{
    
    ArbiGovMessengerL1 public arbiGovMessenger;
    address public auraFarmerL2;
    
    error InsufficientCallValue(uint expected);

    constructor(
        address _gov,
        address _arbiGovMessenger
    ) Governable(_gov) {
        arbiGovMessenger = ArbiGovMessengerL1(payable(_arbiGovMessenger));
    }

    function setAuraFarmerL2(address _auraFarmerL2) external onlyGov {
        auraFarmerL2 = _auraFarmerL2;
    }

    function changeL2Chair(address _newL2Chair) payable external onlyGov {
        bytes4 selector = AuraFarmer.changeL2Chair.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newL2Chair);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }

    function changeL2Guardian(address _newL2Guardian) payable external onlyGov {
        bytes4 selector = AuraFarmer.changeL2Guardian.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newL2Guardian);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }

    function changeL2TWG(address _newL2TWG) payable external onlyGov {
        bytes4 selector = AuraFarmer.changeL2TWG.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newL2TWG);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }

    function changeArbiFedL1(address _newArbiFedL1) payable external onlyGov {
        bytes4 selector = AuraFarmer.changeArbiFedL1.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newArbiFedL1);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }

    function changeArbiGovMessengerL1(address _newArbiGovMessengerL1) payable external onlyGov {
        bytes4 selector = AuraFarmer.changeArbiGovMessengerL1.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newArbiGovMessengerL1);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }

    function changeTreasuryL1(address _newTreasuryL1) payable external onlyGov {
        bytes4 selector = AuraFarmer.changeTreasuryL1.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newTreasuryL1);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }

    function changeMaxLossExpansionBps(uint _newMaxLossExpansionBps) payable external onlyGov {
        bytes4 selector = AuraFarmer.setMaxLossExpansionBps.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newMaxLossExpansionBps);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }

    function changeMaxLossWithdrawBps(uint _newMaxLossWithdrawBps) payable external onlyGov {
        bytes4 selector = AuraFarmer.setMaxLossWithdrawBps.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newMaxLossWithdrawBps);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }

    function changeMaxLossSetableByGuardianBps(uint _newMaxLossSetableByGuardianBps) payable external onlyGov {
        bytes4 selector = AuraFarmer.setMaxLossSetableByGuardianBps.selector;
        if(!arbiGovMessenger.isCallValueSufficient(auraFarmerL2, selector, msg.value))
            revert InsufficientCallValue(arbiGovMessenger.getFunctionMinimumCallValue(auraFarmerL2, selector));
        bytes memory data = abi.encodeWithSelector(selector, _newMaxLossSetableByGuardianBps);
        arbiGovMessenger.sendMessage{value:msg.value}(auraFarmerL2, selector, data);
    }
}
[{"inputs":[{"internalType":"address","name":"_gov","type":"address"},{"internalType":"address","name":"_arbiGovMessenger","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InsufficientCallValue","type":"error"},{"inputs":[],"name":"OnlyGov","type":"error"},{"inputs":[],"name":"OnlyPendingGov","type":"error"},{"inputs":[],"name":"arbiGovMessenger","outputs":[{"internalType":"contract ArbiGovMessengerL1","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auraFarmerL2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newArbiFedL1","type":"address"}],"name":"changeArbiFedL1","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newArbiGovMessengerL1","type":"address"}],"name":"changeArbiGovMessengerL1","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newL2Chair","type":"address"}],"name":"changeL2Chair","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newL2Guardian","type":"address"}],"name":"changeL2Guardian","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newL2TWG","type":"address"}],"name":"changeL2TWG","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxLossExpansionBps","type":"uint256"}],"name":"changeMaxLossExpansionBps","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxLossSetableByGuardianBps","type":"uint256"}],"name":"changeMaxLossSetableByGuardianBps","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxLossWithdrawBps","type":"uint256"}],"name":"changeMaxLossWithdrawBps","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTreasuryL1","type":"address"}],"name":"changeTreasuryL1","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claimPendingGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_auraFarmerL2","type":"address"}],"name":"setAuraFarmerL2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingGov","type":"address"}],"name":"setPendingGov","outputs":[],"stateMutability":"nonpayable","type":"function"}]