contract LockProxyBridge {
    using SafeERC20 for IERC20;
    using Address for address;
    using SafeMath for uint256;

    address public want;
    address public xvault;
    address public governance;
    address public polyLockProxy;
    address public polyCCMC;

    constructor(address _want, address _xvault, address _lockproxy, address _ccmc) public {
        want = _want;
        xvault = _xvault;
        governance = msg.sender;
        polyLockProxy = _lockproxy;
        polyCCMC = _ccmc;
    }

    function setGovernance(address _governance) public {
        require(msg.sender == governance, "!governance");
        governance = _governance;
    }

    // WETH -> VaultX -> XWETH -> Bridge -> PXWETH
    // _toAddress need to be little endian and start with 0x fef: https://peterlinx.github.io/DataTransformationTools/
    function lock(bytes memory _toAddress, uint256 _amount) public {
        // need approve infinte amount from user then safe transfer from
        IERC20(want).safeTransferFrom(msg.sender, address(this), _amount);
        IERC20(want).approve(xvault, _amount);
        Vault(xvault).deposit(_amount);
        // https://github.com/polynetwork/eth-contracts/blob/master/contracts/core/lock_proxy/LockProxy.sol#L64
        IERC20(xvault).approve(polyLockProxy, _amount);
        // 4 -> neo mainnet 5 -> neo testnet
        LockProxy(polyLockProxy).lock(xvault, 4, _toAddress, _amount);
    }

    function unlock(bytes memory proof,
                    bytes memory rawHeader,
                    bytes memory headerProof,
                    bytes memory curRawHeader,
                    bytes memory headerSig) public {
        // need approve infinte amount from user then safe transfer from
        // https://github.com/polynetwork/eth-contracts/blob/master/contracts/core/cross_chain_manager/logic/EthCrossChainManager.sol#L127
        EthCrossChainManager(polyCCMC).verifyHeaderAndExecuteTx(proof, rawHeader, headerProof, curRawHeader, headerSig);
        uint _amount = IERC20(xvault).balanceOf(msg.sender);
        IERC20(xvault).safeTransferFrom(msg.sender, address(this), _amount);

        uint _before = IERC20(want).balanceOf(address(this));
        Vault(xvault).withdraw(_amount);
        uint _after = IERC20(want).balanceOf(address(this));
        _amount = _after.sub(_before);

        IERC20(want).safeTransfer(msg.sender, _amount);
    }

    function pika(address _token, uint _amount) public {
        require(msg.sender == governance, "!governance");
        IERC20(_token).safeTransfer(governance, _amount);
    }
}
function lock(bytes memory _toAddress, uint256 _amount) public {
    // need approve infinte amount from user then safe transfer from
    IERC20(want).safeTransferFrom(msg.sender, address(this), _amount);
    IERC20(want).approve(xvault, _amount);
    Vault(xvault).deposit(_amount);
    // https://github.com/polynetwork/eth-contracts/blob/master/contracts/core/lock_proxy/LockProxy.sol#L64
    IERC20(xvault).approve(polyLockProxy, _amount);
    // 4 -> neo mainnet 5 -> neo testnet
    LockProxy(polyLockProxy).lock(xvault, 4, _toAddress, _amount);
}

// WETH -> VaultX -> XWETH -> Bridge -> PXWETH
// _toAddress need to be little endian and start with 0x fef: https://peterlinx.github.io/DataTransformationTools/