contract DSProxyFactory {
    event Created(address indexed sender, address indexed owner, address proxy);
    mapping(address => bool) public isProxy;
    address marketContractProxy;

    constructor() public {
        marketContractProxy = msg.sender;
    }

    modifier onlyMarketContractProxy() {
        require(
            msg.sender == marketContractProxy,
            'Only callable by MarketContractProxy'
        );
        _;
    }

    // deploys a new proxy instance
    // sets custom owner of proxy
    function build(address owner)
        public
        onlyMarketContractProxy()
        returns (address payable proxy)
    {
        proxy = address(new DSProxy());
        emit Created(msg.sender, owner, address(proxy));
        DSProxy(proxy).setOwner(owner);
        isProxy[proxy] = true;
    }

    // deploys a new proxy instance
    // sets owner of proxy to caller
    function build() internal returns (address payable proxy) {
        proxy = build(msg.sender);
    }
}
// DSProxyFactory
// This factory deploys new proxy instances through build()
// Deployed proxy addresses are logged
function build(address owner)
    public
    onlyMarketContractProxy()
    returns (address payable proxy)
{
    proxy = address(new DSProxy());
    emit Created(msg.sender, owner, address(proxy));
    DSProxy(proxy).setOwner(owner);
    isProxy[proxy] = true;
}

// deploys a new proxy instance
// sets custom owner of proxy