@startuml

!define SHOW_PACKAGES
!include ../doc/dappsys.puml


!ifdef SHOW_PACKAGES
    package TokenAuth.sol {
        interface ERC20Authority
        interface ERC20Auth
        interface TokenAuthority
        interface TokenAuth
    }

    package KycAmlRule.sol {
        interface KycAmlRule
    }

    package NoKycAmlRule.sol {
        class NoKycAmlRule
    }

    package KycAmlERC20.sol {
        class KycAmlERC20
    }

    package solovault.sol {
        class DSSoloVault
    }

    package FiatToken.sol {
        class FiatToken
    }

    package Gate.sol {
        class Gate
    }

    package GateRoles.sol {
        class GateRoles
    }
!endif

interface ERC20Authority #white {
    + canApprove(src, dst, guy, wad)
    + canTransfer(src, dst, to, wad)
    + canTransferFrom(src, dst, from, to, wad)
}

interface ERC20Auth #white {
    + ERC20Authority erc20Authority
    __
    ~ modifier authApprove(guy, wad)
    ~ modifier authTransfer(to, wad)
    ~ modifier authTransferFrom(from, to, wad)
    ..
    + setERC20Authority(erc20Authority) //auth//
    + approve(guy, wad) //authApprove//
    + transfer(dst, wad) //authTransfer//
    + transferFrom(src, dst, wad) //authTransferFrom//
}

interface TokenAuthority #white {
    + canMint(src, dst, guy, wad)
    + canBurn(src, dst, guy, wad)
}

interface TokenAuth #white {
    + TokenAuthority tokenAuthority
    __
    ~ modifier authMint(guy, wad)
    ~ modifier authBurn(guy, wad)
    ..
    + setTokenAuthority(tokenAuthority) //auth//
}

class FiatToken {
    .. Inherited properties ..
    + bytes32 symbol
    + DSAuthority authority
    + ERC20Authority erc20Authority
    + TokenAuthority tokenAuthority
    .. Own properties ..
    __
    + **FiatToken(authority, symbol)**
    + mint(guy, wad) //authMint//
    + burn(guy, wad) //authBurn//
}

class DSSoloVault {
    + ERC20 token
    __
    + swap(ERC20 token_) //auth//
    + push(dst, wad)
    + pull(src, wad)
    + push(dst)
    + pull(src)
    + mint(wad)
    + burn(wad)
    + burn()
    .. Extensions ..
    + mint(guy, wad)
    + burn(guy, wad)
    + approve(guy, wad)
    + approve(guy)
}

interface KycAmlRule  #white {
}

class NoKycAmlRule #white {
    + canApprove(src, dst, guy, wad)
    + canTransfer(src, dst, to, wad)
    + canTransferFrom(src, dst, from, to, wad)
    + canMint(src, dst, guy, wad)
    + canBurn(src, dst, guy, wad)
}

class BoundaryKycAmlRule #white {
    + KycAmlStatus kycAmlStatus
    __
    + canApprove(src, dst, guy, wad)
    + canTransfer(src, dst, to, wad)
    + canTransferFrom(src, dst, from, to, wad)
    + canMint(src, dst, guy, wad)
    + canBurn(src, dst, guy, wad)
}

class FullKycAmlRule #white {
    + KycAmlStatus kycAmlStatus
    __
    + canApprove(src, dst, guy, wad)
    + canTransfer(src, dst, to, wad)
    + canTransferFrom(src, dst, from, to, wad)
    + canMint(src, dst, guy, wad)
    + canBurn(src, dst, guy, wad)
}

class KycAmlStatus #white {
    + {field} (address => bool) kycVerified
    __
    + isKycVerified(guy)
    + setKycVerified(guy, isKycVerified)
}

class GateRoles {
    + OPERATOR = 1
}

class Gate {
    .. Inherited properties ..
    + DSAuthority authority
    + FiatToken token
    .. Own properties ..
    __
    + **Gate(authority, token)**
    + transferFrom(src, dst, wad)
    + checkTransfer(src, dst, wad)
}

'========== Connections ==========

!ifndef DAPPSYS
    interface ERC20
    ERC20 <|-- DSTokenBase
    DSTokenBase <|-- DSToken
!else
    hide DSMultiVault
    hide DSVault
    hide DSGuardFactory
    hide DSNote
!endif

' Force ERC20 and token related auth contracts on the same line
ERC20Auth -[hidden] TokenAuth
TokenAuth -[hidden] ERC20Authority
ERC20Authority -[hidden] TokenAuthority

DSAuth <|-- ERC20Auth
DSAuth <|-- TokenAuth
DSAuth <|-- KycAmlStatus
ERC20Authority <|-- KycAmlRule
TokenAuthority <|-- KycAmlRule
KycAmlRule <|-- NoKycAmlRule
KycAmlRule <|-- BoundaryKycAmlRule
KycAmlRule <|-- FullKycAmlRule

DSRoles <|-- GateRoles
DSToken <|-- FiatToken
ERC20Auth <|-- FiatToken
TokenAuth <|-- FiatToken
DSSoloVault <|-- Gate

BoundaryKycAmlRule o-up- KycAmlStatus
FullKycAmlRule o-up- KycAmlStatus

FiatToken o-up- DSGuard
FiatToken o-up- NoKycAmlRule
FiatToken o-up- BoundaryKycAmlRule
FiatToken o-up- FullKycAmlRule
Gate o-up- GateRoles
'KycAmlStatus o-up- GateRoles
Gate o- FiatToken

@enduml
