contract FixedInflationExtension {
address private _fixedInflationContract;
modifier fixedInflationOnly() {
require(_fixedInflationContract == msg.sender, "Unauthorized");
require(_host == msg.sender, "Unauthorized");
receive() external payable {
function init(address host) public {
require(_host == address(0), "Already init");
require((_host = host) != address(0), "blank host");
_fixedInflationContract = msg.sender;
function setHost(address host) public virtual hostOnly {
function data() view public returns(address fixedInflationContract, address host) {
return(_fixedInflationContract, _host);
function setActive(bool _active) public virtual hostOnly {
function receiveTokens(address[] memory tokenAddresses, uint256[] memory transferAmounts, uint256[] memory amountsToMint) public fixedInflationOnly {
for(uint256 i = 0; i < tokenAddresses.length; i++) {
if(transferAmounts[i] > 0) {
if(tokenAddresses[i] == address(0)) {
(bool result,) = msg.sender.call{value:transferAmounts[i]}("");
require(result, "ETH transfer failed");
_safeTransfer(tokenAddresses[i], msg.sender, transferAmounts[i]);
if(amountsToMint[i] > 0) {
_mintAndTransfer(tokenAddresses[i], msg.sender, amountsToMint[i]);
function setEntry(FixedInflationEntry memory newEntry, FixedInflationOperation[] memory newOperations) public hostOnly {
IFixedInflation(_fixedInflationContract).setEntry(newEntry, newOperations);
function flushBack(address[] memory tokenAddresses) public hostOnly {
IFixedInflation(_fixedInflationContract).flushBack(tokenAddresses);
function deactivationByFailure() public fixedInflationOnly {
function _mintAndTransfer(address erc20TokenAddress, address recipient, uint256 value) internal virtual {
IERC20Mintable(erc20TokenAddress).mint(recipient, value);
function _safeTransfer(address erc20TokenAddress, address to, uint256 value) internal virtual {
bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value));
require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED');
function _call(address location, bytes memory payload) private returns(bytes memory returnData) {
let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0)
let size := returndatasize()
returnData := mload(0x40)
let returnDataPayloadStart := add(returnData, 0x20)
returndatacopy(returnDataPayloadStart, 0, size)
mstore(0x40, add(returnDataPayloadStart, size))
switch result case 0 {revert(returnDataPayloadStart, size)}