Decentralized smart contracts are starting to rely on a centralized software stack.
We've long known that rolling your own cryptography is a recipe for a security compromise, but after the DAO and a number of other multi-million dollar hacks, we know the dangers of rolling our own smart contracts.
Developers know that trusted code bases like OpenZeppelin's ERC-20 token implementation or Compound's governance contracts are likely more secure than something they can develop themselves. These well-known code bases have been audited and rigorously tested.
Unfortunately, humans aren't perfect, and no amount of auditing or testing can protect against all possible vulnerabilities. There are bound to be security flaws in these contracts or their future counterparts.
When a major flaw is uncovered, your system is defenseless until a fix is pushed. This problem is not specific to smart contracts, but unlike legacy application development, smart contracts can be incredibly difficult to upgrade. Hot fixes are usually not possible in isolation and instead require a total system upgrade and migration. This drastically increases the time required to prevent the discovered attack.
Because the field of smart contract development is so nascent, the sources of "trusted" code are small, but highly replicated. A single vulnerability could cause chaos across an entire ecosystem.
Until there are overlapping, equally trusted implementations of all common code, we're stuck with this systemic risk.